简体   繁体   English

引发要显示给用户的异常的最佳实践

[英]Best practices for throwing exceptions that are to be displayed to the user

Unexpected exceptions that should terminate execution of the program are simply thrown. 只会引发意外的异常,这些异常会终止程序的执行。 They are caught by CurrentDomain_UnhandledException and taken care of there - logged if necessary, and a generic "This app is about to crash and you have nothing to do about it" message displayed to the user. 它们被CurrentDomain_UnhandledException捕获,并在那里处理-必要时进行记录,并向用户显示一条通用的“此应用程序将崩溃,您对此无需任何处理”消息。

But what about those exceptions that only need to cancel an operation, while showing the user a more useful message? 但是那些只需要取消操作而向用户显示更有用的消息的异常呢? eg informing the user that a file can't be accessed because it's being used by another process. 例如,通知用户由于另一个进程正在使用该文件而无法访问该文件。 This exception might be deeply nested, and I wouldn't want to check for some flag at every method return. 这个异常可能是深层嵌套的,我不想在每次方法返回时检查一些标志。 I'd rather have something like this: when the user initiates the most "external" method - say, a button click event handler, the code will include a try-catch block catching all DisplayToUserException 's , and rethrow any other exceptions. 我宁愿这样:当用户启动最“外部”的方法(例如,按钮单击事件处理程序)时,代码将包含一个try-catch块,该块捕获所有DisplayToUserException ,并抛出其他异常。 So I'll have to create this custom exception class. 因此,我将不得不创建此自定义异常类。

But before I go down that path, I'd like to know if that's the standard thing to do, or perhaps there's a better solution for this. 但是在我走这条路之前,我想知道这是否是标准做法,或者也许有更好的解决方案。 Or perhaps a class already built for this. 或者也许已经为此建立了一个类。 Hence this question. 因此,这个问题。

It's ok to put a try/catch block around your UI events: 可以在UI事件周围放置try / catch块:

public void Button1_Click(object sender, EventArgs e)
{
    try {
        // Do something interesting, like calling methods that throw (nested) exceptions
        // Maybe these methods do file I/O
    }
    // Though it's better to catch a more-specific exception or set of exceptions
    catch (IOException ex){ 
        MessageBox.Show(ex.ToString());
    }
}

This limits the effects of the exception to the UI operation (the button click, in this case). 这将异常的影响限制在UI操作(在这种情况下为单击按钮)。

A truly unhandled exception, one that you can't anticipate or do anything about, will still get handled by the AppDomain exception handler. AppDomain异常处理程序仍会处理一个真正无法处理的异常,您无法预期或无法做任何事情。

Note also that the Message property of an exception is meant for display to the user. 还请注意, Message的异常的属性指用于显示给用户。 It's ok to catch a "technical" exception, and rethrow as an exception with a user-friendly message. 可以捕获“技术”异常,然后使用用户友好的消息将其作为异常抛出。 But be sure to include the original exception: 但请确保包括原始异常:

try {
    // Do something with the file name in the <c>path</c> variable
}
catch(IOException ex){
    throw new InvalidOperationException(
        String.Format("Can't perform that file I/O on {0}, sorry about that", path), ex);
}

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

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