Files
notifications-api/app/v2/errors.py
Rebecca Law dd126df122 We have a scheduled task to check that all the jobs have completed, this will catch if an app is shut down and the job is complete yet, we only wait 10 seconds before forcing the app to shut down.
The task was raising a JobIncompleteError, yet it's not an error the task is performing it's task correctly and calling the appropriate task to restart the job.
Also used apply_sync to create the task instead of send_task.
2020-07-22 17:00:20 +01:00

94 lines
3.4 KiB
Python

import json
from flask import jsonify, current_app, request
from jsonschema import ValidationError as JsonSchemaValidationError
from notifications_utils.recipients import InvalidEmailError
from sqlalchemy.exc import DataError
from sqlalchemy.orm.exc import NoResultFound
from app.authentication.auth import AuthError
from app.errors import InvalidRequest
class TooManyRequestsError(InvalidRequest):
status_code = 429
message_template = 'Exceeded send limits ({}) for today'
def __init__(self, sending_limit):
self.message = self.message_template.format(sending_limit)
class RateLimitError(InvalidRequest):
status_code = 429
message_template = 'Exceeded rate limit for key type {} of {} requests per {} seconds'
def __init__(self, sending_limit, interval, key_type):
# normal keys are spoken of as "live" in the documentation
# so using this in the error messaging
if key_type == 'normal':
key_type = 'live'
self.message = self.message_template.format(key_type.upper(), sending_limit, interval)
class BadRequestError(InvalidRequest):
message = "An error occurred"
def __init__(self, fields=[], message=None, status_code=400):
self.status_code = status_code
self.fields = fields
self.message = message if message else self.message
class ValidationError(InvalidRequest):
message = "Your notification has failed validation"
def __init__(self, fields=[], message=None, status_code=400):
self.status_code = status_code
self.fields = fields
self.message = message if message else self.message
class PDFNotReadyError(BadRequestError):
def __init__(self):
super().__init__(message='PDF not available yet, try again later', status_code=400)
def register_errors(blueprint):
@blueprint.errorhandler(InvalidEmailError)
def invalid_format(error):
# Please not that InvalidEmailError is re-raised for InvalidEmail or InvalidPhone,
# work should be done in the utils app to tidy up these errors.
current_app.logger.info(error)
return jsonify(status_code=400,
errors=[{"error": error.__class__.__name__, "message": str(error)}]), 400
@blueprint.errorhandler(InvalidRequest)
def invalid_data(error):
current_app.logger.info(error)
response = jsonify(error.to_dict_v2()), error.status_code
return response
@blueprint.errorhandler(JsonSchemaValidationError)
def validation_error(error):
current_app.logger.info(error)
return jsonify(json.loads(error.message)), 400
@blueprint.errorhandler(NoResultFound)
@blueprint.errorhandler(DataError)
def no_result_found(e):
current_app.logger.info(e)
return jsonify(status_code=404,
errors=[{"error": e.__class__.__name__, "message": "No result found"}]), 404
@blueprint.errorhandler(AuthError)
def auth_error(error):
current_app.logger.info('API AuthError, client: {} error: {}'.format(request.headers.get('User-Agent'), error))
return jsonify(error.to_dict_v2()), error.code
@blueprint.errorhandler(Exception)
def internal_server_error(error):
current_app.logger.exception(error)
return jsonify(status_code=500,
errors=[{"error": error.__class__.__name__, "message": 'Internal server error'}]), 500