【问题标题】:Override thrown exception with a new custom expection使用新的自定义异常覆盖引发异常
【发布时间】:2017-02-15 11:39:15
【问题描述】:

我正在尝试将我的服务调用引发的异常覆盖为我自己的自定义异常。我有两个要使用的自定义异常,具体取决于服务调用返回的 StatusCode。 500+ 的 ServerException 或 400+ 错误的 ClientException。

catch (ApiException e)
{
    if ((int)e.StatusCode >= 400 && (int)e.StatusCode < 500)
    {
        throw new ClientException(e.StatusCode.ToString(), e.Message, e.Uri.ToString(), e.HttpMethod, e.Content, e.StatusCode, e.InnerException.Message);
    }
    else
    {
        throw new ServerException(e.StatusCode.ToString(), e.Message, e.Uri.ToString(), e.HttpMethod, e.Content, e.StatusCode, e.InnerException.Message);
    }
}

我需要覆盖示例中捕获的 ApiException。由于某种原因,该示例返回一个带有 ApiException 作为内部异常的异常对象。不返回客户端或服务器异常。

对服务的调用:

catch(ClientException e)
 {}
catch(ServerException e)
 {}
catch (ApiException e)
 {}
catch (Exception e)
 {
  //Always caught here only
 }

ClientException 类,为便于阅读而缩短:

public class ClientException : Exception
{
    public string Code { get; private set; }
    public string ReasonPhrase { get; private set; }
    public ClientException(string code, string message) : base(message)
    {
        Code = code;
        ReasonPhrase = message;
    }
 }

【问题讨论】:

  • 封闭方法不是异步的吗? (即基于任务)
  • 使用 refit 进行服务调用,所以服务调用本身是异步的,但不是保持调用的方法。
  • 您介意展示一下 ClientException 类吗?我假设它是从 Exception 派生的,可能是一个方法实现问题。
  • 这里“返回”的确切异常类型是什么?只是System.Exception 还是其他类型?您是否检查过任何中间代码层,它们是否有自己的 try/catch 块可能是罪魁祸首?
  • 你确定你抛出和捕获的异常类型是一样的吗?我的意思是他们属于同一个图书馆?您共享的异常定义没有接受两个以上参数的构造函数。

标签: c# rest exception exception-handling


【解决方案1】:

我认为您的代码会抛出类似

的 ApiException
public void  foo(){
....
throe new ApiException();
}

在你的代码中你有

try
{
    foo();//throe ApiException
}
catch(ClientException e)
 {}
catch(ServerException e)
 {}
catch (ApiException e)
 {
     var ex=ExceptionLocator.Get(ExceptionCode);//use ExceptionLocator  to locate your custom exception  
     throw ex;
 }
catch (Exception e)
 {
  //Always caught here only
 }

public abstract class BusinessException : Exception
{
    public string Code { get; private set; }
    public string ReasonPhrase { get; private set; }
    public ClientException(string code, string message) : base(message)
    {
        Code = code;
        ReasonPhrase = message;
    }
 }

public class ClientException:BusinessException
{

}

public class ServerException:BusinessException
{

}

public static class ExceptionLocator{
    static Dictionary<int,BusinessException> locator=new Dictionary<int,BusinessException>();

    public ExceptionLocator()
    {
        locator.Add(400,new ClientException());
        locator.Add(500,new ServerException());
        ....
    }
    public static BusinessException Get(int code)
    {
        return locator[code];
    }
}

您可以使用 ExceptionLocator 来定位您的自定义异常或在 Foo() 中决定抛出 ClientException 或 ServerException

【讨论】:

  • 您为 ExceptionLocator 使用了什么库?谢谢
  • @cfl 我更新我的答案
【解决方案2】:

你没有定义接受你的参数的方法

throw new ClientException(
    e.StatusCode.ToString(),
    e.Message, 
    e.Uri.ToString(), 
    e.HttpMethod, 
    e.Content, 
    e.StatusCode, 
    e.InnerException.Message);

你需要类中的方法如

public ClientException(
    string StatusCode,
    string Message, 
    string Uri 
    string HttpMethod, 
    string Content, 
    string StatusCode, 
    string InnerExceptionMessage) : base(...)
{
    ...
}

或者,您可以使用

public ClientException(params object[] args)
        : base(...) { }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 2023-02-17
    相关资源
    最近更新 更多