ServiceStack – Comment désactiver la consignation des exceptions par défaut

Conformément à la documentation ServiceStack , nous disposons d’un gestionnaire d’exception de service global. Les docs disent que ce gestionnaire devrait enregistrer l’exception puis appeler DtoUtils.HandleException , comme ceci:

 private object LogServiceException(object request, Exception exception) { var message = ssortingng.Format("Here we make a custom message..."); _logger.Error(message, exception); return DtoUtils.HandleException(this, request, exception); } 

Il en résulte que l’erreur est consignée deux fois, puisque DTOUtils.HandleException enregistre également , dans un format moins personnalisé. Oui, je préfère de loin ceci à la journalisation de DTOUtils et je ne veux pas simplement l’utiliser.

Comment désactiver l’enregistrement DTOUtils tout en conservant le rest des fonctionnalités? Personne n’aime recevoir deux fois plus de courriels d’erreur qu’ils le devraient.

J’espère que le code suivant résout votre problème.

basé sur la documentation New API, Custom Hooks, ServiceRunner

et gestion fine des erreurs à l’aide de ServiceRunner de la nouvelle API

dans AppHost.Configure

  LogManager.LogFactory = new ServiceStack.Logging.Support.Logging.ConsoleLogFactory(); 

puis en classe AppHost

  public override IServiceRunner CreateServiceRunner(ActionContext actionContext) { return new MyServiceRunner(this, actionContext); } 

dans la classe ServiceRunner

  public class MyServiceRunner : ServiceRunner { public override object HandleException(IRequestContext requestContext, T request, Exception ex) { if ( isYourCondition ) { ResponseStatus rs = new ResponseStatus("error1", "your_message"); // optionally you can add custom response errors rs.Errors = new List(); rs.Errors.Add(new ResponseError()); rs.Errors[0].ErrorCode = "more details 2"; // create an ErrorResponse with the ResponseStatus as parameter var errorResponse = DtoUtils.CreateErrorResponse(request, ex, rs); // log the error Log.Error("your_message", ex); return errorResponse; } else return base.HandleException(requestContext, request, ex); } } 

si vous renvoyez la base.HandleException, il appelle en interne la DtoUtils.HandleException. Vous verrez dans la console une seule erreur de journal.

Dans le client, si vous gérez l’exception WebServiceException pour les erreurs personnalisées.

  catch (WebServiceException err) { if ( err.ResponseStatus.Errors != null) { // do something with err.ResponseStatus.Errors[0].ErrorCode; } } 

DtoUtils.HandleException pas DtoUtils.HandleException car il enregistre l’erreur. DtoUtils.HandleException pas ServiceRunner.HandleException non plus, il appelle DtoUtils.HandleException .

Appelez DtoUtils.CreateErrorResponse pour DtoUtils.CreateErrorResponse la réponse (elle est utilisée par DtoUtils.HandleException ). L’assistant ToResponseStatus est également dans DtoUtils

Mon AppServiceRunner est maintenant comme ceci:

 public class AppServiceRunner : ServiceRunner { public AppServiceRunner(AppHost appHost, ActionContext actionContext) : base(appHost, actionContext) { } public override object HandleException(IRequestContext requestContext, T request, Exception ex) { LogException(requestContext, request, ex); var responseStatus = ex.ToResponseStatus(); return DtoUtils.CreateErrorResponse(request, ex, responseStatus); } private void LogException(IRequestContext requestContext, T request, Exception ex) { // since AppHost.CreateServiceRunner can be called before AppHost.Configure // don't get the logger in the constructor, only make it when it is needed var logger = MakeLogger(); var requestType = typeof(T); var message = ssortingng.Format("Exception at URI:'{0}' on service {1} : {2}", requestContext.AbsoluteUri, requestType.Name, request.ToJson()); logger.Error(message, ex); } private static ILog MakeLogger() { return LogManager.GetLogger(typeof(AppServiceRunner)); } } 

Maintenant, les seules erreurs de service que je reçois sont celles générées par ce code.