繁体   English   中英

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

[英]How to catch all types of exception in one single catch block?

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;
        }
}

但异常不是 System.Net.WebException。 所以不能调用 ex.Status

我的问题:

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

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

我的点子

我称作为所有其他异常类型代表的 Exception 我有命名空间:Common 和两个类representativeAlException.csBusinessExceptionHandler.cs

使用参数创建一个通用函数 (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 块可以处理所有类型的异常

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;
...
...

要处理所有异常,请使用 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 块呢?

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

可以生成简洁、可读代码的另一种方法是使用is运算符,如果您的异常是特定类型的实例或从该类型派生的实例,则该运算符的计算结果为 true。 不幸的是,无法在 switch 块中使用is运算符,因此您必须使用 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;
}

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

提问者的第一次尝试,在问题的代码片段中被注释掉了,现在是最简单的,在我看来也是最好的方法。

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

正如 Onkel-j 推荐的那样,我已经开始使用一系列“if ex is Type”:

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

但是 resharper 建议我让它将其更改为 switch/case:

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

ReSharper的使用了丢弃做一个排序的自动变速器折腾出来的未使用的变量。 如果您需要实际使用异常作为特定类型,请为其命名以代替下划线:

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;
    }
}

应该使用

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
}

最好使用开关

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM