from flask import Flask, jsonify, request, current_app, render_template from pydantic import ValidationError as PydanticValidationError from domain.exceptions import ValidationError, NotFoundError, BusinessError from sqlalchemy.exc import IntegrityError, SQLAlchemyError def register_error_handlers(app: Flask): """Enregistre les gestionnaires d'erreurs globaux.""" @app.errorhandler(ValidationError) def handle_validation_error(error): current_app.logger.warning(f"Erreur de validation : {error}") if request.is_json: return jsonify({'success': False, 'error': str(error)}), 400 return render_template('error.html', error=str(error)), 400 @app.errorhandler(PydanticValidationError) def handle_pydantic_validation_error(error): errors = [] for err in error.errors(): field = '.'.join(str(x) for x in err['loc']) errors.append(f"{field}: {err['msg']}") message = "Données invalides : " + ", ".join(errors) current_app.logger.warning(f"Erreur Pydantic : {message}") if request.is_json: return jsonify({'success': False, 'error': message, 'details': error.errors()}), 400 return render_template('error.html', error=message), 400 @app.errorhandler(NotFoundError) def handle_not_found_error(error): current_app.logger.info(f"Ressource introuvable : {error}") if request.is_json: return jsonify({'success': False, 'error': str(error)}), 404 return render_template('error.html', error=str(error)), 404 @app.errorhandler(BusinessError) def handle_business_error(error): current_app.logger.warning(f"Erreur métier : {error}") if request.is_json: return jsonify({'success': False, 'error': str(error)}), 422 return render_template('error.html', error=str(error)), 422 @app.errorhandler(IntegrityError) def handle_integrity_error(error): current_app.logger.error(f"Erreur d'intégrité DB : {error}") message = "Erreur de données : contrainte de base de données violée" if request.is_json: return jsonify({'success': False, 'error': message}), 409 return render_template('error.html', error=message), 409 @app.errorhandler(SQLAlchemyError) def handle_sqlalchemy_error(error): current_app.logger.error(f"Erreur SQLAlchemy : {error}") message = "Erreur de base de données" if request.is_json: return jsonify({'success': False, 'error': message}), 500 return render_template('error.html', error=message), 500 @app.errorhandler(500) def handle_internal_error(error): current_app.logger.error(f"Erreur interne : {error}") message = "Erreur interne du serveur" if request.is_json: return jsonify({'success': False, 'error': message}), 500 return render_template('error.html', error=message), 500