2017-08-24 68 views
0

当程序出现问题时,您可以在代码中引发异常,并描述问题。典型示例:构建异常消息的最佳做法是什么?

throw new Exception("Houston we have a problem"); 

将硬编码字符串传递给异常构造函数是一种很好的做法吗?也许我应该把所有的异常信息放在一个地方。请告诉我解决异常消息构造问题的最佳做法是什么。

+0

如果lthose异常消息将显示给客户端ocalization是一个问题。但是使用派生自'System.Exception'的自定义异常,这些类型更有意义,可以单独处理。你也可以在那里构造消息,而不是你扔的地方。 –

回答

1

正如Tim在评论中提到的,如果向用户显示消息,本地化可能会成为问题。

我在这个主题上的做法是什么,我真正想提出的是以下内容。

试着使它通用

Makea一个常量类牵着你的异常信息,像这样meaningfull常量名:

public static const String IN_VARIABLE_MISSING = "An expected value is missing. Please try again"; 

这会给你真正重新使用任何需要它异常的能力。 (你也只需要在一个地方进行编辑,并在任何地方更新)你可以构建一个包装器来处理本地化。但是这个话题有很多选择,我不会详细说明。

所以,你可以再抛出一个异常,这样的:

throw new Exception(IN_VARIABLE_MISSING); 

如果是这样,这将可以使用市售我也建议写一个自己的异常延伸的标准异常的软件。

为什么?

你喜欢这个,你可以创建一个例外,将您的信息和例如一个号码,将自动生成一个唯一的密钥:

IN-MODULE-NUMBER-IDENTIFICATION 

您看到这可能是很方便?在本地化和迅速找到它发生的地方以及发生的原因。

您可以修改它以在内部错误的开始处编写INVA验证错误。然后是所发生的课程/项目,然后是一个数字或任何你想要的。

该系统还将使您能够使用该密钥的另一个字符串,具体取决于用户使用的区域设置。

TL; DR使其可重复使用!

+0

C#中没有final关键字!改用const。 –

+0

不好意思来自Java。将更正它 – Nico

+0

塞巴斯蒂安里克特,谢谢你的回答。这是否意味着使用具有常量的类是最好的方法?为什么不字典,例如? – pepeevich

2

将硬编码字符串传递给异常构造函数是一种很好的做法吗?

是和否

throw new Exception("Houston we have a problem"); 

是主叫处理更难:

在这个意义上,该代码

没有。这是因为意味着的例外仅由消息的文本标识;因此,想要从代码中捕获异常的调用者(例如,以免崩溃,但如果可能的话继续运行)必须进行字符串比较以找出问题所在。

例如

try 
{ 
    someService.DoSomething(sessionId) 
} 
catch(Exception ex) 
{ 
    if (ex.Message.Contains("Houston")) 
    { 
     //this indicates that someService couldn't connect to the database 
    } 
    else if(ex.Message.Contains("is on fire")) 
    { 
     //someService detected that the network is exploded 
    } 
    else{ 
    //we can only handle the two previous cases, all else is passed on} 
    throw;  
} 

正如你可以看到这个就会变得混乱很快,如果有人更改文本....

现在这个代码,而另一方面:

throw new SomethingSpecificWentWrongException(sessionId); 

其中SomethingSpecificWentWrongException可能看起来像这样:

public class SomethingSpecificWentWrongException: Exception 
{ 
    public int SessionId {get;protected set;} 
    public SomethingSpecificWentWrongException(int sessionId): 
    base($"Something specific went horribly wrong with session {sessionId}") 
    { 
    SessionId=sessionId; 
    } 
} 

很容易调用者进行处理:

try 
{ 
    someService.DoSomething(sessionId) 
} 
catch(SomethingSpecificWentWrongException ex) 
{ 
    //do whatever it is you do to recover from this 
} 
catch(SomethingElseSpecificWentWrongException wex) 
{ 
    //recover from this 
} 
else 
{ 
throw; 
} 

你会发现,这里有一个硬编码的上下的字符串,但它是由自定义异常类本身所拥有,而不是由决定抛出异常的代码;这有很大的区别,因为这意味着你可以保证在使用这个异常的地方消息是可预测的(就日志记录等而言)。 因此,不仅推理起来更容易,而且比由投掷代码提供的硬编码字符串更易于维护。

+0

对不起,也许我写错了,但问题是关于异常消息,它不是关于用户/自定义异常。我可以将硬编码字符串传递给异常构造函数,或者我可以使用字典或其他异常消息的其他字符,并使用字典项传递给异常构造函数而不是硬编码字符串。这是我的问题。 – pepeevich

+0

@pepeevich - 公平点。我在回答你在文本中提出的问题 - “将硬编码字符串传递给异常构造函数是否是一种好习惯?”。结合这种方法和尼科答案中的方法可能会给你一个全面的答案。请注意,直接使用'Exception'通常不被认为是一种好习惯,你应该使用自定义例外:) 如果你想让这个重新开放,也许你可以重新解释这个问题,更普遍地问什么是一个好的方法,持有一个字符串,旨在被一个人阅读。 –

相关问题