ServiceStack utility (WebServiceException ex) - has the wrong ErrorCode code

In my ServiceStack service, I am creating an exception that has an internal exception. When I caught WebServiceRequest on the client side, ErrorCode was an internal exception type name.

This is bad for me because it does not allow me to respond to the specific type of exception that was thrown to the server.

I do not understand why ServiceStack was designed this way. It is pretty typical to catch exceptions at a lower level and wrap them with more informative and sometimes user-friendly exceptions.

How can I change the default behavior, so it uses surface level exception, not internal?

+4
source share
2 answers

After looking at the first example at https://github.com/ServiceStack/ServiceStack/wiki/Error-Handling , I decided to check for DtoUtils .HandleException, which looks like this:

public static object HandleException(IResolver iocResolver, object request, Exception ex) { if (ex.InnerException != null && !(ex is IHttpError)) ex = ex.InnerException; var responseStatus = ex.ToResponseStatus(); if (EndpointHost.DebugMode) { // View stack trace in tests and on the client responseStatus.StackTrace = GetRequestErrorBody(request) + ex; } Log.Error("ServiceBase<TRequest>::Service Exception", ex); if (iocResolver != null) LogErrorInRedisIfExists(iocResolver.TryResolve<IRedisClientsManager>(), request.GetType().Name, responseStatus); var errorResponse = CreateErrorResponse(request, ex, responseStatus); return errorResponse; } 

The very first instruction replaces the exception with an internal exception. I'm not sure what this is up to. It seems to me that it seems intuitive to me, and therefore I just repeated the method in the AppHost class, removing this first if if block:

  public override void Configure(Container container) { ServiceExceptionHandler += (request, exception) => HandleException(this, request, exception); } /// <remarks> /// Verbatim implementation of DtoUtils.HandleException, without the innerexception replacement. /// </remarks> public static object HandleException(IResolver iocResolver, object request, Exception ex) { var responseStatus = ex.ToResponseStatus(); if (EndpointHost.DebugMode) { // View stack trace in tests and on the client responseStatus.StackTrace = DtoUtils.GetRequestErrorBody(request) + ex; } var log = LogManager.GetLogger(typeof(DtoUtils)); log.Error("ServiceBase<TRequest>::Service Exception", ex); if (iocResolver != null) DtoUtils.LogErrorInRedisIfExists(iocResolver.TryResolve<IRedisClientsManager>(), request.GetType().Name, responseStatus); var errorResponse = DtoUtils.CreateErrorResponse(request, ex, responseStatus); return errorResponse; } 

This is obviously not ideal, as I had to copy a bunch of code that is completely unrelated to the problem that I encountered with the original implementation. It seems to me that I should support this method whenever I update ServiceStack. I wish there was a better way to achieve this.

Anyway, I have exception handling that I like in my client code:

 catch (WebServiceException ex) { if (ex.ErrorCode == typeof (SomeKindOfException).Name) { // do something useful here } else throw; } 
+3
source

You don't seem to have to support a bunch of code. You write one method for implementing your own error handling. You can try to call DtoUtils.HandleException (this, request, exception) in your own method and change the returned HttpError object. Not sure if you have access to modify all the properties / values ​​you are looking for.

 public static object HandleException(IResolver iocResolver, object request, Exception ex) { HttpError err = (HttpError)DtoUtils.HandleException(this, request, ex); err.Reponse = ex.InnerException; } 
+1
source

All Articles