# Path: via/exceptions.py
# class BadURL(RequestBasedException):
#     """An invalid URL was discovered."""
# 
#     def __init__(self, message, requests_err=None, url=None):
#         super().__init__(message, requests_err)
#         self.url = url
# 
#     status_int = 400
# 
# class GoogleDriveServiceError(UpstreamServiceError):
#     """Something interesting happened in Google Drive.
# 
#     We often use the more generic versions, but if there's something of
#     particular interest, we might raise this error.
#     """
# 
#     def __init__(self, message, status_int, requests_err=None):
#         super().__init__(message, requests_err=requests_err)
# 
#         self.status_int = status_int
# 
# class UnhandledUpstreamException(UpstreamServiceError):
#     """Something we did not plan for went wrong."""
# 
#     status_int = 417
# 
# class UpstreamServiceError(RequestBasedException):
#     """Something went wrong when calling an upstream service."""
# 
#     status_int = 409
# 
# Path: via/views/exceptions.py
# EXCEPTION_MAP = {
#     BadURL: {
#         "title": "The URL isn't valid",
#         "long_description": [
#             "Parts of the URL could be missing or in the wrong format."
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
#     UpstreamTimeout: {
#         "title": "Timeout",
#         "long_description": ["The web page we tried to get took too long to respond."],
#         "stage": "upstream",
#         "retryable": True,
#     },
#     UnhandledUpstreamException: {
#         "title": "Something went wrong",
#         "long_description": ["We experienced an unexpected error."],
#         "stage": "via",
#         "retryable": True,
#     },
#     UpstreamServiceError: {
#         "title": "Could not get web page",
#         "long_description": [
#             "Something went wrong when we tried to get the web page.",
#             "It might be missing or might have returned an error.",
#         ],
#         "stage": "upstream",
#         "retryable": True,
#     },
#     HTTPNotFound: {
#         "title": "Page not found",
#         "long_description": [
#             "The URL you asked for is not part of this service.",
#             "Please check the URL you have entered.",
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
#     HTTPClientError: {
#         "title": "Bad request",
#         "long_description": [
#             "We can't process the request because we don't understand it."
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
# }
# 
# @exception_view_config(Exception, route_name="proxy_google_drive_file", renderer="json")
# @exception_view_config(
#     Exception, route_name="proxy_google_drive_file:resource_key", renderer="json"
# )
# def google_drive_exceptions(exc, request):
#     """Catch all errors for Google Drive and display an HTML page."""
# 
#     # Don't log 404's as they aren't very interesting
#     if not isinstance(exc, HTTPNotFound):
#         h_pyramid_sentry.report_exception(exc)
# 
#     _set_status(exc, request)
# 
#     data = {
#         "exception": exc.__class__.__name__,
#         "message": str(exc.args[0]) if exc.args else None,
#     }
# 
#     if hasattr(exc, "response") and exc.response is not None:
#         data["upstream"] = _serialise_requests_info(exc.request, exc.response)
# 
#     return data
# 
# @exception_view_config(Exception, renderer="via:templates/exception.html.jinja2")
# def other_exceptions(exc, request):
#     """Catch all errors (Pyramid or Python) and display an HTML page."""
# 
#     # We don't want to log errors from upstream services or things which are
#     # the user goofing about making bad queries.
#     if not isinstance(exc, (UpstreamServiceError, BadURL, HTTPClientError)):
#         h_pyramid_sentry.report_exception(exc)
# 
#     return _get_error_body(exc, request)


import json
import pytest
from io import BytesIO
from unittest.mock import sentinel
from h_matchers import Any
from pyramid.httpexceptions import (
    HTTPClientError,
    HTTPGatewayTimeout,
    HTTPNotFound,
    HTTPUnsupportedMediaType,
)
from pyramid.testing import DummyRequest
from pytest import param
from requests import HTTPError, Request, Response
from via.exceptions import (
    BadURL,
    GoogleDriveServiceError,
    UnhandledUpstreamException,
    UpstreamServiceError,
)
from via.views.exceptions import (
    EXCEPTION_MAP,
    google_drive_exceptions,
    other_exceptions,
)
        response.raw = BytesIO(json.dumps(json_body).encode("utf-8"))
        response.headers["Content-Type"] = "mime/type"

        exception = GoogleDriveServiceError(
            "message", 419, HTTPError(request=request, response=response)
        )

        result = google_drive_exceptions(exception, pyramid_request)

        assert result == {
            "exception": "GoogleDriveServiceError",
            "message": "message",
            "upstream": {
                "content_type": response.headers["Content-Type"],
                "json": json_body,
                "status_code": response.status_code,
                "url": request.url,
            },
        }

        json.dumps(result)  # Check we are serialisable

        assert pyramid_request.response.status_int == 419

    @pytest.mark.parametrize(
        "raw,expected_text", ((123456, "... cannot retrieve ..."), (None, ""))
    )
    def test_it_with_bad_response(self, pyramid_request, raw, expected_text):
        response = Response()
        response.raw = raw

# Path: via/exceptions.py
# class BadURL(RequestBasedException):
#     """An invalid URL was discovered."""
# 
#     def __init__(self, message, requests_err=None, url=None):
#         super().__init__(message, requests_err)
#         self.url = url
# 
#     status_int = 400
# 
# class GoogleDriveServiceError(UpstreamServiceError):
#     """Something interesting happened in Google Drive.
# 
#     We often use the more generic versions, but if there's something of
#     particular interest, we might raise this error.
#     """
# 
#     def __init__(self, message, status_int, requests_err=None):
#         super().__init__(message, requests_err=requests_err)
# 
#         self.status_int = status_int
# 
# class UnhandledUpstreamException(UpstreamServiceError):
#     """Something we did not plan for went wrong."""
# 
#     status_int = 417
# 
# class UpstreamServiceError(RequestBasedException):
#     """Something went wrong when calling an upstream service."""
# 
#     status_int = 409
# 
# Path: via/views/exceptions.py
# EXCEPTION_MAP = {
#     BadURL: {
#         "title": "The URL isn't valid",
#         "long_description": [
#             "Parts of the URL could be missing or in the wrong format."
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
#     UpstreamTimeout: {
#         "title": "Timeout",
#         "long_description": ["The web page we tried to get took too long to respond."],
#         "stage": "upstream",
#         "retryable": True,
#     },
#     UnhandledUpstreamException: {
#         "title": "Something went wrong",
#         "long_description": ["We experienced an unexpected error."],
#         "stage": "via",
#         "retryable": True,
#     },
#     UpstreamServiceError: {
#         "title": "Could not get web page",
#         "long_description": [
#             "Something went wrong when we tried to get the web page.",
#             "It might be missing or might have returned an error.",
#         ],
#         "stage": "upstream",
#         "retryable": True,
#     },
#     HTTPNotFound: {
#         "title": "Page not found",
#         "long_description": [
#             "The URL you asked for is not part of this service.",
#             "Please check the URL you have entered.",
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
#     HTTPClientError: {
#         "title": "Bad request",
#         "long_description": [
#             "We can't process the request because we don't understand it."
#         ],
#         "stage": "request",
#         "retryable": False,
#     },
# }
# 
# @exception_view_config(Exception, route_name="proxy_google_drive_file", renderer="json")
# @exception_view_config(
#     Exception, route_name="proxy_google_drive_file:resource_key", renderer="json"
# )
# def google_drive_exceptions(exc, request):
#     """Catch all errors for Google Drive and display an HTML page."""
# 
#     # Don't log 404's as they aren't very interesting
#     if not isinstance(exc, HTTPNotFound):
#         h_pyramid_sentry.report_exception(exc)
# 
#     _set_status(exc, request)
# 
#     data = {
#         "exception": exc.__class__.__name__,
#         "message": str(exc.args[0]) if exc.args else None,
#     }
# 
#     if hasattr(exc, "response") and exc.response is not None:
#         data["upstream"] = _serialise_requests_info(exc.request, exc.response)
# 
#     return data
# 
# @exception_view_config(Exception, renderer="via:templates/exception.html.jinja2")
# def other_exceptions(exc, request):
#     """Catch all errors (Pyramid or Python) and display an HTML page."""
# 
#     # We don't want to log errors from upstream services or things which are
#     # the user goofing about making bad queries.
#     if not isinstance(exc, (UpstreamServiceError, BadURL, HTTPClientError)):
#         h_pyramid_sentry.report_exception(exc)
# 
#     return _get_error_body(exc, request)


# Path: tests/unit/via/views/exceptions_test.py
import json
import pytest
from io import BytesIO
from unittest.mock import sentinel
from h_matchers import Any
from pyramid.httpexceptions import (
    HTTPClientError,
    HTTPGatewayTimeout,
    HTTPNotFound,
    HTTPUnsupportedMediaType,
)
from pyramid.testing import DummyRequest
from pytest import param
from requests import HTTPError, Request, Response
from via.exceptions import (
    BadURL,
    GoogleDriveServiceError,
    UnhandledUpstreamException,
    UpstreamServiceError,
)
from via.views.exceptions import (
    EXCEPTION_MAP,
    google_drive_exceptions,
    other_exceptions,
)

        response.raw = BytesIO(json.dumps(json_body).encode("utf-8"))
        response.headers["Content-Type"] = "mime/type"

        exception = GoogleDriveServiceError(
            "message", 419, HTTPError(request=request, response=response)
        )

        result = google_drive_exceptions(exception, pyramid_request)

        assert result == {
            "exception": "GoogleDriveServiceError",
            "message": "message",
            "upstream": {
                "content_type": response.headers["Content-Type"],
                "json": json_body,
                "status_code": response.status_code,
                "url": request.url,
            },
        }

        json.dumps(result)  # Check we are serialisable

        assert pyramid_request.response.status_int == 419

    @pytest.mark.parametrize(
        "raw,expected_text", ((123456, "... cannot retrieve ..."), (None, ""))
    )
    def test_it_with_bad_response(self, pyramid_request, raw, expected_text):
        response = Response()
        response.raw = raw

        exception = GoogleDriveServiceError(