from flask import render_template, jsonify, request, send_from_directory, current_app import logging import os from sqlalchemy.exc import SQLAlchemyError, OperationalError, IntegrityError logger = logging.getLogger(__name__) def register_error_handlers(app): @app.errorhandler(400) def handle_400_error(e): logger.error(f'400 error: {str(e)}') if request.path.startswith('/calculate'): return jsonify({'error': 'Invalid request parameters'}), 400 return render_template('errors/400.html'), 400 @app.errorhandler(403) def handle_403_error(e): logger.error(f'403 error: {str(e)}') if request.path.startswith('/calculate'): return jsonify({'error': 'Access forbidden'}), 403 return render_template('errors/403.html'), 403 @app.errorhandler(404) def handle_404_error(e): logger.error(f'404 error: {str(e)}') if request.path.startswith('/calculate'): return jsonify({'error': 'Resource not found'}), 404 if request.path.startswith('/static/'): app.logger.warning(f'Static file not found: {request.path}') return '', 404 return render_template('errors/404.html'), 404 @app.errorhandler(500) def handle_500_error(e): logger.error(f'500 error: {str(e)}') app.logger.error(f'Server error: {str(e)}') if request.path.startswith('/calculate'): return jsonify({'error': 'Internal server error'}), 500 if request.path.startswith('/static/'): app.logger.error(f'Error serving static file {request.path}: {str(e)}') return '', 404 return render_template('errors/500.html'), 500 @app.errorhandler(OperationalError) def handle_db_operational_error(error): logger.error(f'Database operational error: {str(error)}', exc_info=True) if request.path.startswith('/api/'): return jsonify({ 'error': 'Database connection error', 'message': 'Unable to connect to the database. Please try again later.' }), 503 return render_template('errors/503.html', message='Database connection error. Please try again later.'), 503 @app.errorhandler(IntegrityError) def handle_db_integrity_error(error): logger.error(f'Database integrity error: {str(error)}', exc_info=True) if request.path.startswith('/api/'): return jsonify({ 'error': 'Database integrity error', 'message': 'The operation could not be completed due to data constraints.' }), 409 return render_template('errors/409.html', message='The operation could not be completed due to data constraints.'), 409 @app.errorhandler(SQLAlchemyError) def handle_db_error(error): logger.error(f'Database error: {str(error)}', exc_info=True) if request.path.startswith('/api/'): return jsonify({ 'error': 'Database error', 'message': 'An unexpected database error occurred.' }), 500 return render_template('errors/500.html', message='An unexpected database error occurred.'), 500 @app.errorhandler(Exception) def handle_unhandled_exception(e): logger.error(f'Unhandled exception: {str(e)}', exc_info=True) app.logger.error(f'Unhandled exception: {str(e)}', exc_info=True) if request.path.startswith('/calculate'): return jsonify({'error': 'Internal server error'}), 500 if request.path.startswith('/static/'): app.logger.error(f'Error serving static file {request.path}: {str(e)}') return '', 404 return render_template('errors/500.html'), 500