Gestionnaire d'erreurs
Toute application sera confrontée à une situation dans laquelle un problème se produit et nous ne pouvons pas fournir de solution autre que d'en informer l'utilisateur. Par exemple, l'utilisateur essaie de récupérer une ressource inexistante.
Gestion des exceptions
Dans une application Web créée avec Fano Framework, toutes les exceptions non gérées étant générées seront gérées par l'instance d'interface IErrorHandler.
Cette interface possède une méthode :
Paramètres
Paramètre | Description |
---|---|
env | Est un énumérateur de variables d'environnement. |
exc | Est une instance d'exception à gérer. |
status | Est la valeur entière du code HTTP à envoyer au client. |
msg | Est la valeur de chaîne du message HTTP à envoyer au client. |
Les gestionnaires d'erreurs sont enregistrés dans la méthode buildErrorHandler() du fournisseur de services d'application, comme indiqué dans l'exemple de code ci-dessous.
Exceptions
Le Fano Framework définit certaines classes d'exceptions correspondant au code d'erreur HTTP :
Classe | Message d'erreur | Description |
---|---|---|
EBadRequest | HTTP 400 Bad Request. | Ce code d'erreur permet d'indiquer qu'une mauvaise requête est envoyé à la page. |
EUnauthorized | HTTP 401 Unauthorized. | Ce code d'erreur permet d'indiquer qu'une autorisation est requise pour cette page. |
EForbidden | HTTP 403 Forbidden | Ce code d'erreur permet d'indiquer que l'accès à cette page est refusé. |
ENotFound | HTTP 404 Not Found. | Le code d'erreur 404 permet d'indiquer permet d'indiquer que la page Web ou le fichier est introuvable. |
EMethodNotAllowed | HTTP 405 Method Not Allowed. | Ce message d'erreur permet d'indiquer que les méthodes HTTP utiliser pour l'action au serveur Web n'est pas autorisé. |
ENotAcceptable | HTTP 406 Not Acceptable. | Ce message d'erreur permet d'indiquer que les données ou le nom de la page n'est pas acceptable sur le serveur Apache. |
EGone | HTTP 410 Gone. | Ce code d'erreur permet d'indiquer que la page est partie. |
EUnsupportedMediaType | HTTP 415 Unsupported Media Type. | Ce code d'erreur permet d'indiquer que le type de support de média n'est pas supporté par la page. |
EUnprocessableEntity | HTTP 422 Unprocessable Entity. | Ce code d'erreur permet d'indiquer une entité ne pouvant être un processus d'une page. |
ETooManyRequest | HTTP 429 Too Many Request. | Ce code d'erreur permet d'indiquer que le client (généralement défini par l'adresse IP) a envoyé trop de demandes au cours d'une période donnée. |
EInternalServerError | HTTP 500 Internal Server Error. | Cette erreur permet d'indiquer qu'une erreur interne du serveur Web empêche de retourner la page. |
ENotImplemented | HTTP 501 Not Implemented. | Ce code d'erreur permet d'indiquer que la méthode n'est pas mise en oeuvre. |
EBadGateway | HTTP 502 Bad Gateway. | Ce code d'erreur permet d'indiquer que la méthode n'est pas mise en oeuvre. |
EServiceUnavailable | HTTP 503 Service Unavailable. | Ce code d'erreur permet d'indiquer que le serveur est temporairement non-disponible. |
EGatewayTimeout | HTTP 504 Gateway Timeout. | Ce code d'erreur permet d'indiquer que le délai est dépassé sur le chemin du réseau. |
Si vous déclenchez l'une des exceptions ci-dessus, Fano Framework renvoie son erreur HTTP correspondante en réponse. Toutes les classes d'exception ci-dessus sont dérivées de la classe EHttpException.
Le Fano Framework définit également d'autres exceptions non liées au code d'erreur HTTP. Chacune de ces exceptions entraînera une réponse d'erreur HTTP 500, à l'exception de ERouteHandlerNotFound entraînant une erreur HTTP 404.
Implémentation du gestionnaire d'erreurs intégré
Le Fano Framework est fourni avec plusieurs implémentations IErrorHandler :
Implémentation | Description |
---|---|
TFancyErrorHandler | Gestionnaire d'erreurs de base par défaut générant l'erreur dans un code HTML thématique. Vous l'utilisez principalement à des fins de développement car il affiche des informations d'erreur détaillées. |
TErrorHandler | Gestionnaire d'erreurs de base générant l'erreur au format HTML simple. Vous l'utilisez principalement à des fins de développement car il affiche des informations d'erreur détaillées. |
TAjaxErrorHandler | Gestionnaire d'erreurs générant des informations d'erreur au format JSON. |
TNullErrorHandler | Gestionnaire d'erreurs ne générant rien d'autre qu'une erreur HTTP. |
THtmlAjaxErrorHandler | Gestionnaire d'erreurs composite générant une erreur HTML de base ou JSON selon que la demande est AJAX ou non. |
TLogErrorHandler | Gestionnaire d'erreurs enregistrant les informations d'erreur au lieu de les transmettre au client. |
TLoggerErrorHandler | Gestionnaire d'erreurs similaire à TLogErrorHandler, sauf qu'il peut déterminer le niveau de journalisation à enregistrer. Par exemple, il peut enregistrer uniquement les journaux de type critique. |
TTemplateErrorHandler | Gestionnaire d'erreurs générant une erreur à l'aide d'un gabarit HTML. Cette classe est fournie pour permettre au développeur d'afficher une page d'erreur bien formatée. Pour une configuration de production, c'est principalement ce que vous utilisez. |
TCompositeErrorHandler | Gestionnaire d'erreurs composé de deux autres gestionnaires d'erreurs. Il est fourni pour combiner, par exemple, l'enregistrement des erreurs dans un fichier et l'affichage d'une sortie bien formatée sur le client. Pour combiner trois gestionnaires d'erreurs ou plus, vous devez les connecter en guirlande. |
TGroupErrorHandler | Gestionnaire d'erreurs composé d'un ou plusieurs gestionnaires d'erreurs. Il est similaire au gestionnaire d'erreurs composite ci-dessus, sauf qu'il est plus flexible car vous pouvez composer un nombre arbitraire de gestionnaires d'erreurs. |
TDecoratorErrorHandler | Gestionnaire d'erreurs abstrait qui décore un autre gestionnaire d'erreurs. |
TConditionalErrorHandler | Gestionnaire d'erreurs abstrait sélectionnant l'un des deux gestionnaires d'erreurs en fonction d'une condition. Le descendant doit implémenter sa méthode abstraite condition(). |
TBoolErrorHandler | Gestionnaire d'erreurs sélectionnant l'un des deux gestionnaires d'erreurs en fonction d'une condition spécifiée dans le paramètre du constructeur. |
TNotFoundErrorHandler | Gestionnaire d'erreurs sélectionnant l'un des deux gestionnaires d'erreurs en fonction d'une condition si l'exception est ERouteHandlerNotFound. Cela vous permet de gérer l'erreur HTTP 404 séparément, par exemple pour afficher un gabarit HTML différent pour l'erreur HTTP 404. |
TMethodNotAllowedErrorHandler | Gestionnaire d'erreurs sélectionnant l'un des deux gestionnaires d'erreurs en fonction d'une condition si l'exception est EMethodNotAllowed. Cela vous permet de gérer l'erreur HTTP 405 séparément, par exemple pour utiliser un gabarit HTML différent pour l'erreur HTTP 405. |
TInternalServerErrorHandler | Gestionnaire d'erreurs sélectionnant l'un des deux gestionnaires d'erreurs en fonction d'une condition si l'exception est EInternalServerError. Cela vous permet de gérer les erreurs HTTP 500 séparément, par exemple pour utiliser un gabarit HTML différent pour les erreurs HTTP 500. |
Afficher un message d'erreur détaillé
TFancyErrorHandler et TErrorHandler sont des implémentations de base d'IErrorHandler, affichant des informations d'erreur de base dans le type de contenu HTML, telles que le type d'exception déclenchée, le message d'exception et les variables d'environnement et de trace de pile.
Si vous compilez une application avec des informations de débogage telles que le drapeau -g ou -gh, la trace de pile est assez détaillée, comme le numéro de ligne dans le fichier source. Sans informations de débogage, elle affiche uniquement l'emplacement de la mémoire.
Par défaut, lorsque vous héritez du fournisseur de services d'application de TBasicAppServiceProvider, vous utilisez le gestionnaire d'erreurs TFancyErrorHandler.
Pour enregistrer un type de gestionnaire d'erreurs différent, vous devez remplacer la méthode buildErrorHandler().
Afficher un message d'erreur détaillé au format JSON
- Type
- TAppServiceProvider=Class(TBasicAppServiceProvider)
- Protected
- Function buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ):IErrorHandler; override;
- ...
- End;
- ...
-
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ) : IErrorHandler;
- Begin
- Result:=TAjaxErrorHandler.create();
- End;
Masquer le message d'erreur
Erreur d'affichage avec le gabarit HTML
Enregistrer l'erreur dans le fichier
Vous devez vous assurer que /path/to/log/file est accessible en écriture.
Ou si vous souhaitez enregistrer uniquement les messages d'urgence et critiques, utilisez plutôt TLoggerErrorHandler.
Enregistrer l'erreur dans un fichier et afficher l'erreur à partir du modèle
Utilisez TCompositeErrorHandler ou TGroupErrorHandler pour composer plusieurs gestionnaires d'erreurs en un seul.
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ):IErrorHandler;
- Begin
- Result:=TCompositeErrorHandler.create(
- TLogErrorHandler.create(TFileLogger.create('/path/to/log/file')),
- TTemplateErrorHandler.create('/path/to/error/template.html')
- );
- End;
ou avec TGroupErrorHandler :
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ):IErrorHandler;
- Begin
- Result:=TGroupErrorHandler.create([
- TLogErrorHandler.create(TFileLogger.create('/path/to/log/file')),
- TTemplateErrorHandler.create('/path/to/error/template.html')
- ]);
- End;
Enregistrer l'erreur dans un fichier et afficher une page d'erreur vide
Composer plusieurs gestionnaires d'erreurs
Utilisez TCompositeErrorHandler avec la connexion en guirlande ou TGroupErrorHandler pour composer plusieurs gestionnaires d'erreurs en un seul.
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ):IErrorHandler;
- Begin
- Result:=TCompositeErrorHandler.create(
- TCompositeErrorHandler.create(
- //Journal dans un fichier et STDERR
- TLogErrorHandler.create(TFileLogger.create('/path/to/log/file')),
- TLogErrorHandler.create(TStdErrLogger.create())
- ),
- TTemplateErrorHandler.create('/path/to/error/template.html')
- );
- End;
ou avec TGroupErrorHandler
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ) : IErrorHandler;
- Begin
- //enregistrer l'erreur dans le fichier et STDERR et afficher également le modèle d'erreur
- Result:=TGroupErrorHandler.create([
- TLogErrorHandler.create(TFileLogger.create('/path/to/log/file')),
- TLogErrorHandler.create(TStdErrLogger.create()),
- TTemplateErrorHandler.create('/path/to/error/template.html')
- ]);
- End;
Sélectionnez un gestionnaire d'erreurs différent en fonction de la configuration de production ou de développement
- Function TAppServiceProvider.buildErrorHandler(
- Const ctnr:IDependencyContainer;
- Const config:IAppConfiguration
- ):IErrorHandler;
- Var prodErrHandler:IErrorHandler;
- devErrHandler:IErrorHandler;
- isProd:Boolean;
- Begin
- prodErrHandler:=TCompositeErrorHandler.create(
- TLogErrorHandler.create(TFileLogger.create('/path/to/log/file')),
- TTemplateErrorHandler.create('/path/to/error/template.html')
- );
- devErrHandler:=TErrorHandler.create();
- isProd:=config.getBool('isProduction');
- result:=TBoolErrorHandler.create(
- prodErrHandler,
- devErrHandler,
- isProd
- );
- End;
Créez votre propre gestionnaire d'erreurs
Si vous trouvez que les gestionnaires d'erreurs intégrés ne suffisent pas pour votre cas d'utilisation, vous pouvez créer votre propre implémentation IErrorHandler.
- Unit myerrorhandler;
-
- INTERFACE
-
- {$MODE OBJFPC}
- {$H+}
-
- Uses
- fano;
-
- Type
- TMyErrorHandler=Class(TInterfacedObject,IErrorHandler)
- Public
- Function handleError(
- Const env:ICGIEnvironmentEnumerator;
- Const exc:Exception;
- Const status:Integer=500;
- Const msg:String ='Erreur interne du serveur'
- ) : IErrorHandler;
- end;
-
- IMPLEMENTATION
-
- Function TMyErrorHandler.handleError(
- Const env:ICGIEnvironmentEnumerator;
- Const exc:Exception;
- Const status:Integer=500;
- Const msg:String ='Erreur interne du serveur'
- ):IErrorHandler;
- Begin
- Writeln('Content-Type: text/html');
- Writeln('Status: ', status, ' ', msg) ;
- Writeln();
- Writeln('Message d'erreur bizarre');
- Result:=self;
- End;
-
- END.
Les lignes suivantes sont obligatoires pour se conformer au protocole CGI :
Pour utiliser votre propre gestionnaire d'erreurs :