-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.py
More file actions
134 lines (116 loc) · 4.54 KB
/
Copy patherrors.py
File metadata and controls
134 lines (116 loc) · 4.54 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""Error handling module for the Flask application."""
from flask import jsonify, render_template, request, flash, redirect, url_for
import structlog
from werkzeug.exceptions import HTTPException
from flask_wtf.csrf import CSRFError
from functools import wraps
logger = structlog.get_logger()
class APIError(Exception):
"""Base exception for API errors."""
def __init__(self, message, status_code=400, payload=None):
super().__init__()
self.message = message
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or {})
rv['error'] = self.message
rv['status_code'] = self.status_code
return rv
def handle_api_error(error):
"""Handle API errors."""
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
def handle_404_error(error):
"""Handle 404 Not Found errors."""
logger.warning("404 - Page not found",
path=request.path,
method=request.method)
if request.path.startswith('/api/'):
return jsonify({
'error': 'Resource not found',
'status_code': 404
}), 404
return render_template('errors/404.html'), 404
def handle_csrf_error(error):
"""Handle CSRF validation errors."""
logger.warning("CSRF validation failed",
path=request.path,
method=request.method,
error=str(error))
if request.path.startswith('/api/'):
return jsonify({
'error': 'CSRF validation failed',
'message': str(error),
'status_code': 400
}), 400
flash('Erro de segurança: token CSRF inválido. Por favor, tente novamente.', 'error')
return redirect(url_for('main.index'))
def handle_500_error(error):
"""Handle 500 Internal Server errors."""
logger.error("500 - Internal server error",
error_info=str(error),
path=request.path,
method=request.method,
exc_info=True)
if request.path.startswith('/api/'):
return jsonify({
'error': 'Internal server error',
'status_code': 500
}), 500
return render_template('errors/500.html'), 500
def handle_413_error(error):
"""Handle 413 Request Entity Too Large errors."""
from flask import current_app
logger.warning("413 - File too large",
path=request.path,
content_length=request.content_length)
response = {
'error': 'File too large',
'message': 'The uploaded file exceeds the maximum allowed size.',
'max_size_mb': current_app.config.get('MAX_CONTENT_LENGTH', 0) / (1024 * 1024)
}
if request.path.startswith('/api/'):
return jsonify(response), 413
return render_template('errors/413.html', **response), 413
def init_error_handlers(app):
"""Initialize error handlers for the application."""
app.register_error_handler(APIError, handle_api_error)
app.register_error_handler(404, handle_404_error)
app.register_error_handler(500, handle_500_error)
app.register_error_handler(413, handle_413_error)
app.register_error_handler(CSRFError, handle_csrf_error)
@app.errorhandler(Exception)
def handle_unexpected_error(error):
"""Handle any unhandled exceptions."""
logger.error("Unhandled exception",
error_type=type(error).__name__,
error_str=str(error),
path=request.path,
method=request.method,
exc_info=True)
if request.path.startswith('/api/'):
return jsonify({
'error': 'An unexpected error occurred',
'status_code': 500
}), 500
return render_template('errors/500.html'), 500
def api_error_handler(f):
"""Decorator to handle API endpoint errors consistently."""
@wraps(f)
async def decorated_function(*args, **kwargs):
try:
return await f(*args, **kwargs)
except APIError as e:
return handle_api_error(e)
except Exception as e:
logger.error(f"API endpoint error in {f.__name__}",
error_type=type(e).__name__,
error_str=str(e),
exc_info=True)
return jsonify({
'error': 'An unexpected error occurred',
'status_code': 500
}), 500
return decorated_function