mirror of
https://github.com/GSA/notifications-api.git
synced 2026-05-17 15:31:08 -04:00
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.
94 lines
3.4 KiB
Python
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
|