2010-10-22 44 views
3

捕获所有异常并将它们作为特定类型重新抛出是一种很好的做法 - 基本上将从应用程序的特定部分(或服务)抛出的所有异常进行分类?捕获所有异常并将它们作为分类方面的特定类型异常重新抛出是否是一种好的做法?

喜欢的东西:

// This class is used to label all the exceptions occured on 
// Race Cars Service calls as RaceCarsServiceException 
public class RaceCarsServiceException : Exception 
{ 

public class RaceCarsServiceException (Exception e) 
       : base("Something went wrong!", e) 
    { 
    // Basically I assign the exception e as the inner exception 
    //by using the constructor method of Exception class 
    } 

} 

public class RaceCarsService 
{ 

// Some member fields, methods etc. here 

public double GetMaxSpeed(CarModel model) 
{ 
    try 
    { 
     return (double)_carsWebService.GetMaxSpeed(model.ToString()); 
    } 

    catch(Exception e) 
    { 
     throw new RaceCarsServiceException(e); // So all exceptions are rethrown 
              //as type of RaceCarsServiceException 
    } 
} 
} 

回答

1

此代码示例不重新抛出异常,但创建其他新一个基地。

该代码将创建新的堆栈跟踪。

good practice for exceptions

+0

我不同意,因为你不知道他的结构如何实现。更多我经常需要这两个堆栈跟踪,因为有多种代码路径可以到达相同的地方 – 2010-10-22 09:00:52

2

这是那些巨大的争论startingt问题之一。

如果您正在抛出自定义异常,它们不应该直接从内部表达式映射,如您的示例中所示。您应该进行某种条件检查,以区分您对特定自定义异常的具体需求,以及可能抛出的各种可能的异常。

在我看来,如果在恰当的地方适度地完成这项工作,这样做可能会非常有益。

对于我构建的一个应用程序,我们需要能够使用传入的参数来追踪每个函数调用,以便我们可以识别导致异常的精确事件链。

有时候内部的异常不够细化。或者你需要抛出一个异常来告诉你什么样的过程失败了。

例如,如果您的代码必须是事务性的,但是可以跨多个服务工作,因此需要一些手工代码来处理事务,那么事务异常是适用的,就像事务回滚异常一样(这意味着您是在一个痛苦的世界里)。

无论我认识那些强烈认为自定义异常是件坏事的人,原因在于容易被人拿走并创造太多对其他人毫无意义和无用的习惯用法。

我想到的一件事是RecordDoesNotExist异常感觉像是DAL异常,但实际上它发生并在业务逻辑中经常处理。

所以总之,我认为他们是在适当的地方,适度和有充分理由的好主意。但它很容易与他们有点ott。

您应该始终将原始的expcetion传递给您的自定义异常并将其存储在那里。这样可以保留堆栈跟踪,并将堆栈跟踪存储在异常中的自定义堆栈抛出点。

我在审核它们时使用自定义excpetions是一项要求。

编辑: 在对方的回答我得以下链接后说,这是excpetions一个伟大的文章

Exception Handling Best Practices in .NET

随着这一个有关反 - 模式

Exception Anti-Patterns

0

没有必要这样做(至少在你的例子中)。当试图调用可能抛出异常的方法时,分别处理不同类型的异常。

try 
{ 
    AMethodMayThrowExceptions(); 
} 
catch (FileNotFoundException fileEx) 
{ 
     //maybe create the file and retry 
} 
catch (TimeoutException timeoutEx) 
{ 
     //maybe a retry after n seconds 
} 
catch (Exception ex) 
{ 
     //other exceptions which I don't care 
     //just a prompt of ex.Message or something 
} 

如果您使用单个RaceCarsServiceException,会发生什么?

catch (RaceCarsServiceException ex) 
{ 
    // now it's supposed to have a `ErrorCode` property, or an inner exception 
    if (ex.ErrorCode == ErrorCode.File) 
     //file exception, everything is the same with FileNotFoundException 
    else ... 
} 

你得到的只是麻烦和可读性较差的代码!

+0

但是我可以为这种情况创建更多从RaceCarsServiceException派生的异常类型。 – pencilCake 2010-10-22 09:13:01

+0

许多内置的.net异常应该恕我直言,不会抛出用户代码,因为调用'Foo'的代码可以区分两种非常不同的情况:(1)根据'Foo'的文档,应该抛出'InvalidOperationException'; (2)'Foo'调用了一个抛出'InvalidOperationException'但是'Foo'的方法并没有期待这样的异常,并且没有捕获它。请注意,条件#1可能发生在'Foo'调用抛出异常'Foo' *的方法*期望的方法时。应该如何区分#1和#2? – supercat 2012-10-29 18:36:31

相关问题