https://github.com/ServiceStack/ServiceStack/wiki/Error-Handlingで最初の例を見た後、次のようなDtoUtils .HandleExceptionを確認することにしました。
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;
}
最初の命令は、例外をその内部例外に置き換えます。私はそれで何を考えていたのか分かりません。私には直感に反するように思われるので、AppHost クラスのメソッドを再実装し、最初の if ステートメント ブロックを削除しました。
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;
}
元の実装で発生した問題とはまったく関係のない一連のコードをコピーする必要があったため、これは明らかに理想的ではありません。ServiceStack を更新するたびに、このメソッドを維持する必要があるように感じます。これを達成するためのより良い方法をここで紹介したいと思います。
とにかく、私は私のクライアントコードで好きな例外処理をしています:
catch (WebServiceException ex)
{
if (ex.ErrorCode == typeof (SomeKindOfException).Name)
{
// do something useful here
}
else throw;
}