从函数返回错误信息的最佳方法是什么?

问题描述:

如果面对一个逻辑错误错误,如(Expired user, invalid ID),那么什么是告诉从下面这个错误的父类的方法的最佳方式:从函数返回错误信息的最佳方法是什么?

1-抛出定制例外,像下面这样:

try 
{ 
//if (ID doesn't match) then 
Throw new CustomException(-1,"ID doesn't match"); 
} 
catch(CustomException ex) 
{ 
throw ex 
} 
catch(Exception ex) 
{ 
throw new CustomException(ex.ErrorCode,ex.message); 
} 

2 - 返回错误消息和代码,如:

//if (ID doesn't match) then 
This.ErrorCode= -1; 
This.Message= "ID doesn't match"; 
+1

**尝试**,** catch **和** throw **,第一个是最好的.. – NetStarter 2013-04-08 07:24:19

+1

请参阅[此问题](http://stackoverflow.com/questions/3926086/handling-已知的错误和错误的消息-IN-A-方法?RQ = 1)。 – 2013-04-08 07:24:38

+0

我现在可以为什么? – 2013-04-08 07:24:48

更好的方法是抛出自定义异常。这就是为什么他们被介绍。如果您需要提供具体信息,如ErrorCode或其他内容,则可以轻松扩展基类Exception。主要理由是:

  • 您可以忽略从funcion返回无效的错误代码,这可能导致你到你的系统状态被破坏,而Exception的情况是你不能忽视。
  • 如果你的功能有用,那么它应该返回一些你感兴趣的数据而不是错误代码,这会给你更坚实的设计。

在大多数情况下,您应该抛出异常。这是标准还是自定义异常取决于上下文,但与流程无关。

抛出异常强制任何实现相应地处理坏数据。如果您依赖实现来检查属性值是否正确处理,那么意外,难以调试的异常迟早会遇到。

我想你应该使用异常,因为它是确切的,它们是什么。你可以在那里放置相同的信息,就像在第二种情况下一样。但是第一个和第二个之间的区别在于你给功能消费者一个可能被告知有问题的可能性,并且它以某种方式被处理。在第二种情况下,您只是说该功能起作用,但出错了,并且用户可能处理此信息

它完全取决于您的项目工作流程。如果它是一个意外的运行计时器错误,它抑制了你的程序,然后异常是一个不错的选择,但对于简单的输入检查和可预期的产出,你应该使用枚举

如果面对一个逻辑错误错误,例如(过期的用户,无效的ID ),那么什么是告诉这个错误的父类的方法的最好办法

  1. 既然你想要的父类的方法知道的错误,它的接缝,你是不知道,ID是啥User在您致电GetUser方法之前没有过期。对?

  2. 如果您不确定传递给函数的参数是否有效,那么使用异常是不合理的,您应该返回错误信息。

  3. 您可以返回错误信息更多功能方式类似于Scala,Go和Rust语言建议。

创建一个泛型类返回任何错误或值

public class Either(of ErrorType, ValueType) 
    public readonly Success as boolean 
    public readonly Error as ErrorType 
    public readonly Value as ValueType 

    public sub new(Error as ErrorType) 
     me.Success = False 
     me.Error = Error 
    end sub 

    public sub new(Value as ValueType) 
     me.Success = True 
     me.Value = Value 
    end sub 
end class 

创建错误的枚举,你的函数可以有

public enum UserError 
    InvalidUserID 
    UserExpired 
end enum 

创建一个函数,用户ID作为参数并返回错误或用户

function GetUser(ID as integer) as Either(of UserError, User) 

    if <business logic to find a user failed> then 
     return new Either(of UserError, User)(UserError.InvalidUserID) 
    end if 

    if <user expired> then 
     return new Either(of UserError, User)(UserError.UserExpired) 
    end if 

    return new Either(of UserError, User)(User) 
end function 

在了错误的调用者(父母)的方法检查,并应用业务逻辑

dim UserID = 10 
dim UserResult = GetUser(10) 

if UserResult.Success then 
    rem apply business logic to UserResult.Value 
else 
    rem apply business logic to UserResult.Error 
end if 

注:如果您使用改写例外,你会得到完全同样的代码量的代码。