mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-05 11:09:55 -06:00
155 lines
5.9 KiB
Python
155 lines
5.9 KiB
Python
from flask import render_template, request, jsonify
|
|
from werkzeug.exceptions import HTTPException
|
|
import traceback
|
|
|
|
def get_user_friendly_message(status_code, error_description=None):
|
|
"""Get user-friendly error messages"""
|
|
messages = {
|
|
400: {
|
|
'title': 'Invalid Request',
|
|
'message': 'The request was invalid. Please check your input and try again.',
|
|
'recovery': ['Go to Dashboard', 'Go Back']
|
|
},
|
|
401: {
|
|
'title': 'Authentication Required',
|
|
'message': 'You need to log in to access this feature.',
|
|
'recovery': ['Go to Login']
|
|
},
|
|
403: {
|
|
'title': 'Access Denied',
|
|
'message': 'You don\'t have permission to perform this action.',
|
|
'recovery': ['Go to Dashboard', 'Go Back']
|
|
},
|
|
404: {
|
|
'title': 'Page Not Found',
|
|
'message': 'The page or resource you\'re looking for was not found.',
|
|
'recovery': ['Go to Dashboard', 'Go Back']
|
|
},
|
|
409: {
|
|
'title': 'Conflict',
|
|
'message': 'This action conflicts with existing data. Please refresh and try again.',
|
|
'recovery': ['Refresh Page', 'Go Back']
|
|
},
|
|
422: {
|
|
'title': 'Validation Error',
|
|
'message': 'Please check your input and try again.',
|
|
'recovery': ['Go Back']
|
|
},
|
|
429: {
|
|
'title': 'Too Many Requests',
|
|
'message': 'You\'ve made too many requests. Please wait a moment and try again.',
|
|
'recovery': ['Refresh Page']
|
|
},
|
|
500: {
|
|
'title': 'Server Error',
|
|
'message': 'A server error occurred. Our team has been notified. Please try again later.',
|
|
'recovery': ['Refresh Page', 'Go to Dashboard']
|
|
},
|
|
502: {
|
|
'title': 'Service Unavailable',
|
|
'message': 'The server is temporarily unavailable. Please try again later.',
|
|
'recovery': ['Refresh Page']
|
|
},
|
|
503: {
|
|
'title': 'Service Unavailable',
|
|
'message': 'Service temporarily unavailable. Please try again in a few moments.',
|
|
'recovery': ['Refresh Page']
|
|
},
|
|
504: {
|
|
'title': 'Request Timeout',
|
|
'message': 'The request took too long. Please try again.',
|
|
'recovery': ['Refresh Page', 'Go Back']
|
|
}
|
|
}
|
|
|
|
if status_code in messages:
|
|
msg = messages[status_code].copy()
|
|
if error_description:
|
|
msg['message'] = f"{msg['message']} ({error_description})"
|
|
return msg
|
|
|
|
return {
|
|
'title': 'Error',
|
|
'message': error_description or 'An error occurred. Please try again.',
|
|
'recovery': ['Go to Dashboard', 'Go Back']
|
|
}
|
|
|
|
def register_error_handlers(app):
|
|
"""Register error handlers for the application"""
|
|
|
|
@app.errorhandler(404)
|
|
def not_found_error(error):
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(404)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), 404
|
|
error_info = get_user_friendly_message(404)
|
|
return render_template('errors/404.html', error_info=error_info), 404
|
|
|
|
@app.errorhandler(500)
|
|
def internal_error(error):
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(500)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), 500
|
|
error_info = get_user_friendly_message(500)
|
|
return render_template('errors/500.html', error_info=error_info), 500
|
|
|
|
@app.errorhandler(403)
|
|
def forbidden_error(error):
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(403)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), 403
|
|
error_info = get_user_friendly_message(403)
|
|
return render_template('errors/403.html', error_info=error_info), 403
|
|
|
|
@app.errorhandler(400)
|
|
def bad_request_error(error):
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(400)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), 400
|
|
error_info = get_user_friendly_message(400)
|
|
return render_template('errors/400.html', error_info=error_info), 400
|
|
|
|
@app.errorhandler(HTTPException)
|
|
def handle_http_exception(error):
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(error.code, error.description)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), error.code
|
|
error_info = get_user_friendly_message(error.code, error.description)
|
|
return render_template('errors/generic.html', error=error, error_info=error_info), error.code
|
|
|
|
@app.errorhandler(Exception)
|
|
def handle_exception(error):
|
|
# Log the error
|
|
app.logger.error(f'Unhandled exception: {error}')
|
|
app.logger.error(traceback.format_exc())
|
|
|
|
if request.path.startswith('/api/'):
|
|
error_info = get_user_friendly_message(500)
|
|
return jsonify({
|
|
'error': error_info['message'],
|
|
'title': error_info['title'],
|
|
'recovery': error_info['recovery']
|
|
}), 500
|
|
error_info = get_user_friendly_message(500)
|
|
return render_template('errors/500.html', error_info=error_info), 500
|