-
Notifications
You must be signed in to change notification settings - Fork 25
/
errors.py
114 lines (91 loc) · 4.17 KB
/
errors.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from flask import current_app, json, jsonify
from jsonschema import ValidationError as JsonSchemaValidationError
from marshmallow import ValidationError
from notifications_utils.eventlet import EventletTimeout
from notifications_utils.recipient_validation.errors import InvalidRecipientError
from sqlalchemy.exc import DataError
from sqlalchemy.orm.exc import NoResultFound
from app.authentication.auth import AuthError
from app.exceptions import ArchiveValidationError
class VirusScanError(Exception):
def __init__(self, message):
super().__init__(message)
class InvalidRequest(Exception):
code = None
fields = []
def __init__(self, message, status_code):
super().__init__()
self.message = message
self.status_code = status_code
def to_dict(self):
return {"result": "error", "message": self.message}
def to_dict_v2(self):
"""
Version 2 of the public api error response.
"""
return {
"status_code": self.status_code,
"errors": [{"error": self.__class__.__name__, "message": self.message}],
}
def __str__(self):
return f"InvalidRequest: status_code={self.status_code}; message={self.message}"
def register_errors(blueprint): # noqa: C901
@blueprint.errorhandler(InvalidRecipientError)
def invalid_format(error):
return jsonify(result="error", message=str(error)), 400
@blueprint.errorhandler(AuthError)
def authentication_error(error):
return jsonify(result="error", message=error.message), error.code
@blueprint.errorhandler(ValidationError)
def marshmallow_validation_error(error):
current_app.logger.info(error)
return jsonify(result="error", message=error.messages), 400
@blueprint.errorhandler(JsonSchemaValidationError)
def jsonschema_validation_error(error):
current_app.logger.info(error)
return jsonify(json.loads(error.message)), 400
@blueprint.errorhandler(ArchiveValidationError)
def archive_validation_error(error):
current_app.logger.info(error)
return jsonify(result="error", message=str(error)), 400
@blueprint.errorhandler(InvalidRequest)
def invalid_data(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
current_app.logger.info(error)
return response
@blueprint.errorhandler(400)
def bad_request(e):
msg = e.description or "Invalid request parameters"
current_app.logger.exception(msg)
return jsonify(result="error", message=str(msg)), 400
@blueprint.errorhandler(401)
def unauthorized(e):
error_message = "Unauthorized: authentication token must be provided"
return jsonify(result="error", message=error_message), 401, [("WWW-Authenticate", "Bearer")]
@blueprint.errorhandler(403)
def forbidden(e):
error_message = "Forbidden: invalid authentication token provided"
return jsonify(result="error", message=error_message), 403
@blueprint.errorhandler(429)
def limit_exceeded(e):
current_app.logger.exception(e)
return jsonify(result="error", message=str(e.description)), 429
@blueprint.errorhandler(NoResultFound)
@blueprint.errorhandler(DataError)
def no_result_found(e):
current_app.logger.info(e)
return jsonify(result="error", message="No result found"), 404
@blueprint.errorhandler(EventletTimeout)
def eventlet_timeout(error):
current_app.logger.exception(error)
return jsonify(result="error", message="Timeout serving request"), 504
# this must be defined after all other error handlers since it catches the generic Exception object
@blueprint.app_errorhandler(500)
@blueprint.errorhandler(Exception)
def internal_server_error(e):
# if e is a werkzeug InternalServerError then it may wrap the original exception. For more details see:
# https://flask.palletsprojects.com/en/1.1.x/errorhandling/?highlight=internalservererror#unhandled-exceptions
e = getattr(e, "original_exception", e)
current_app.logger.exception(e)
return jsonify(result="error", message="Internal server error"), 500