Passed
Pull Request — develop (#964)
by
unknown
01:24
created

failed_not_found()   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
"""
2
Module containing error views.
3
"""
4
5
import logging
6
import sys
7
8
from pyramid.httpexceptions import HTTPMethodNotAllowed
9
from pyramid.view import notfound_view_config
10
from pyramid.view import view_config
11
from pyramid_openapi3 import RequestValidationError
12
from pyramid_openapi3 import ResponseValidationError
13
from pyramid_openapi3 import extract_errors
14
from pyramid_openapi3 import openapi_validation_error
15
from skosprovider.exceptions import ProviderUnavailableException
16
from sqlalchemy.exc import IntegrityError
17
18
from atramhasis.errors import SkosRegistryNotFoundException
19
from atramhasis.errors import ValidationError
20
from atramhasis.protected_resources import ProtectedResourceException
21
22
23
log = logging.getLogger(__name__)
24
25
26
@notfound_view_config(accept='application/json', renderer='json')
27
@notfound_view_config(accept='text/html', renderer='notfound.jinja2')
28
def failed_not_found(exc, request):
29
    """
30
    View invoked when a resource could not be found.
31
    """
32
    log.debug(exc.explanation)
33
    request.response.status_int = 404
34
    return {'message': exc.explanation}
35
36
37
@view_config(
38
    accept='application/json', context=SkosRegistryNotFoundException, renderer='json'
39
)
40
@view_config(
41
    accept='text/html',
42
    context=SkosRegistryNotFoundException,
43
    renderer='notfound.jinja2',
44
)
45
def failed_skos(exc, request):
46
    """
47
    View invoked when Atramhasis can't find a SKOS registry.
48
    """
49
    log.error(exc.value, exc_info=sys.exc_info())
50
    request.response.status_int = 404
51
    return {'message': exc.value}
52
53
54
@view_config(accept='application/json', context=ValidationError, renderer='json')
55
def failed_validation(exc, request):
56
    """
57
    View invoked when bad data was submitted to Atramhasis.
58
    """
59
    log.debug(f"'message': {exc.value}, 'errors': {exc.errors}")
60
    request.response.status_int = 400
61
    return {'message': exc.value, 'errors': exc.errors}
62
63
64
@view_config(
65
    accept='application/json', context=ProtectedResourceException, renderer='json'
66
)
67
def protected(exc, request):
68
    """
69
    when a protected operation is called on a resource that is still referenced
70
    """
71
    log.warning(f"'message': {exc.value}, 'referenced_in': {exc.referenced_in}")
72
    request.response.status_int = 409
73
    return {'message': exc.value, 'referenced_in': exc.referenced_in}
74
75
76
@view_config(
77
    accept='application/json', context=ProviderUnavailableException, renderer='json'
78
)
79
def provider_unavailable(exc, request):
80
    """
81
    View invoked when ProviderUnavailableException was raised.
82
    """
83
    log.error(exc, exc_info=sys.exc_info())
84
    request.response.status_int = 503
85
    return {'message': exc.message}
86
87
88
@view_config(accept='application/json', context=IntegrityError, renderer='json')
89
def data_integrity(exc, request):
90
    """
91
    View invoked when IntegrityError was raised.
92
    """
93
    log.warning(exc)
94
    request.response.status_int = 409
95
    return {
96
        'message': 'this operation violates the data integrity and could not be executed'
97
    }
98
99
100
@view_config(accept='application/json', context=Exception, renderer='json')
101
@view_config(accept='text/html', context=Exception, renderer='error.jinja2')
102
def failed(exc, request):  # pragma no cover
103
    """
104
    View invoked when bad data was submitted to Atramhasis.
105
    """
106
    log.error(exc, exc_info=sys.exc_info())
107
    request.response.status_int = 500
108
    return {'message': 'unexpected server error'}
109
110
111
@view_config(accept='application/json', context=HTTPMethodNotAllowed, renderer='json')
112
def failed_method_not_allowed(exc, request):  # pragma no cover
113
    """
114
    View invoked when a method is not allowed.
115
    """
116
    log.debug(exc.explanation)
117
    request.response.status_int = 405
118
    return {'message': exc.explanation}
119
120
121
@view_config(accept='application/json', context=RequestValidationError, renderer='json')
122
@view_config(
123
    accept='application/json', context=ResponseValidationError, renderer='json'
124
)
125
def failed_openapi_validation(exc, request):
126
    try:
127
        errors = [
128
            f'{error.get("field")}: {error["message"]}'
129
            for error in list(extract_errors(request, exc.errors))
130
        ]
131
        request.response.status_int = 400
132
        if isinstance(exc, RequestValidationError):
133
            subject = 'Request'
134
        else:
135
            subject = 'Response'
136
        return {'message': f'{subject} was not valid for schema.', 'errors': errors}
137
    except Exception as e:
138
        log.exception('Issue with exception handling.')
139
        return openapi_validation_error(exc, request)
140