如何在一个catch块中捕获所有类型的异常?

时间:2012-10-04 00:59:57

标签: c# .net web-services exception

catch(Exception ex)
{
    //do what you want here

    //When type of exception is System.Web.Services.Protocols.SoapException
    //if (ex.Code.Name.Equals("Client"))
    //{
    //      msg = "service's function not exist";
    //}
    //else if (ex.Code.Name.Equals("Server"))
    //{
    //     msg = "function error"
    //}
    //else
    //{
    //     msg = "unknown";
    //}
    //MessageBox.Show(msg, "error", MessageBoxButtons.OK);

**But ex is not System.Web.Services.Protocols.SoapException so I cannot call ex.Code.Name.Equals("Client")**


//When System.Net.WebException
//switch (ex.Status)
//{
//   case System.Net.WebExceptionStatus.ConnectFailure:
//              do some thing
                break;
//   case System.Net.WebExceptionStatus.Timeout:
                //do some thing
                break;
//    case System.Net.WebExceptionStatus.ProtocolError:
            switch (((System.Net.HttpWebResponse)ex.Response).StatusCode)
            {
                  case System.Net.HttpStatusCode.NotFound:
                        //do some thing
                        break;
                    case System.Net.HttpStatusCode.ServiceUnavailable:
                        //do some thing
                        break;
                    case System.Net.HttpStatusCode.Unauthorized:
                        //do some thing
                        break;
                    default:
                        //do some thing
                        break;
                }
                break;
            default:
                //do some thing
                break;
        }
}

但是Exception不是System.Net.WebException。所以不能打电话给ex.Status

我的问题:

我有一个Smartclient软件包括WindowsForm作为客户端和web服务作为服务器。 客户端和服务器都是n层应用程序 我已经测试过,发现从客户端调用服务时有任何问题

    在app.config中的
  1. :service的路径wrrong。我抓住 System.NotSupportedException
  2. 或者当服务器无法连接时: System.Net.WebExceptionStatus
  3. 服务器的webconfig错误: System.InvalidOperationException
  4. 服务抛出异常: System.Web.Services.Protocols.SoapException ...
  5. 我的想法

    我将异常称为所有其他异常类型的代表是 representativeAlException 我有命名空间:Common和两个classese representativeAlException.cs BusinessExceptionHandler.cs

    使用param创建一个通用函数(representativeAlException ex)

                try
                {
                    Err_LogCheck.Service1.Service1 service = new Err_LogCheck.Service1.Service1();
                    return service.getDeviceByZero(ZERO);
                }
                catch (Common.representativeAlException ex)
                {
                    Common.BusinessExceptionHandler.ProcessException(ex);
                }
    

    我想做什么

    调用服务的位置。只有一个catch块可以处理所有类型的Exception

    ProcessException(representativeAlException ex)函数

    中的

    switch (ex)
    {
    case System.InvalidOperationException:
     //Do some thing
     break;
    case System.NotSupportedException:
     //Do some thing
     break;
    case System.Web.Services.Protocols.SoapException:
     //do some thing
     break;
    ...
    ...
    

4 个答案:

答案 0 :(得分:12)

要处理所有异常,请使用Exception类。

try
{

}
catch(Exception ex)
{
     switch (ex.GetType().ToString())
     {
         case "System.InvalidOperationException":
              //cast ex to specific type of exception to use it's properties
              ((InvalidOperationException)ex).SomeMethod();
         break;
         case "System.NotSupportedException":
             ((System.NotSupportedException)ex).AnotherMethod();
         break;
         case "System.Web.Services.Protocols.SoapException":
             ((System.Web.Services.Protocols.SoapException)ex).OtherMethod();
         break;
     }

}

为什么你不能只使用多个catch块?

答案 1 :(得分:3)

这是现在的语言功能。只需使用switch / case语句

提问者的第一次尝试已在问题的代码段中注释掉了,这是最简单的方法,也是我认为最好的方法。

在尝试弄清楚Resharper对其建议的一项改进所做的工作时,我实际上遇到了这个问题。我仍然不确定100%涉及的术语,因为我能找到的唯一文档是对Discards的解释,并且仅提及传递也在执行的“与is和switch关键字匹配的模式”。

正如Onkel-j所建议的那样,我开始时带有“ if ex is Type”链:

try
{
    doWork();
}
catch (Exception ex)
{
    if (ex is SpecificExceptionType)
    {
        //todo
    }
    else 
    {
        //etc
    }
}

但是resharper建议我让它将其更改为开关/案例:

try
{
    doWork();
}
catch (Exception ex)
{
    switch (ex)
    {
        case SpecificExceptionType _:
            //todo
            break;            
        default:
            //etc
            break;
    }
}

Resharper使用Discards进行了 automatic is 的一种操作,并丢弃未使用的变量。如果您需要实际将异常用作作为特定类型,请为其指定一个名称,以代替下划线:

try
{
    doWork();
}
catch (Exception ex)
{
    switch (ex)
    {
        case SpecificExceptionType specific:
            HandleSpecificException(specific);
            break;            
        default:
            //etc
            break;
    }
}

或者回答原始问题:

catch(Exception ex)
{
    //do what you want here
    
    switch(ex)
    {
        case System.Web.Services.Protocols.SoapException soapEx:        
            if (soapEx.Code.Name.Equals("Client"))
            {
                  msg = "service's function not exist";
            }
            else if (soapEx.Code.Name.Equals("Server"))
            {
                 msg = "function error"
            }
            else
            {
                 msg = "unknown";
            }
            MessageBox.Show(msg, "error", MessageBoxButtons.OK);    
            break;
        case System.Net.WebException webEx:
            switch (webEx.Status)
            {
               case System.Net.WebExceptionStatus.ConnectFailure:
                    //do some thing
                    break;
               case System.Net.WebExceptionStatus.Timeout:
                    //do some thing
                    break;
                case System.Net.WebExceptionStatus.ProtocolError:
                    switch (((System.Net.HttpWebResponse)webEx.Response).StatusCode)
                    {
                        case System.Net.HttpStatusCode.NotFound:
                            //do some thing
                            break;
                        case System.Net.HttpStatusCode.ServiceUnavailable:
                            //do some thing
                            break;
                        case System.Net.HttpStatusCode.Unauthorized:
                            //do some thing
                            break;
                        default:
                            //do some thing
                            break;
                    }
                    break;
                default:
                    //do some thing
                    break;
            }
            break;
        default:
            //etc
            break;
    }
}

答案 2 :(得分:2)

User2808350 是正确的,因为某种原因尝试捕获块可能有许多不同的捕获,但有时您会发现在使用此模式时您正在重复自己(DRY)。

可以产生简洁,可读代码的替代方法是使用运算符,如果您的异常是特定类型的实例或从该类型派生的实例,则该运算符的计算结果为true。不幸的是,在交换机块中不能使用运算符,所以你必须使用if-then-else。

以下是我测试异常类型并相应设置退出代码的示例。

try
{
    // try something
}
catch (Exception e)
{
    if (e is FileNotFoundException)
        Environment.ExitCode = 2;
    else if (e is InvalidOperationException)
        Environment.ExitCode = 1;
    else
        Environment.ExitCode = 42;
    throw;
}

答案 3 :(得分:1)

应该使用

try {

    ....

}
catch (System.Net.HttpStatusCode.NotFound)
{
 //do some thing
}    
catch (System.Net.HttpStatusCode.ServiceUnavailable)
{
 //do some thing
}

catch (System.Net.HttpStatusCode.Unauthorized)
{
 //do some thing
}

catch (System.Net.HttpStatusCode.NotFound)
{
 //do some thing
}    
catch (Exception)
{
 //do some thing
}

使用swicth

更好