windows:Messages/errors/design-concepts
出自UXGuide.net
错误信息:设计理念
Error Messages: Design Concepts
目录 |
糟糕的错误信息的特征
大量令人厌烦的、无用的、写得很糟糕的错误信息已经令我们习以为常。而且,由于错误信息往往是通过模式对话框呈现的,因此它们会打断用户当前的活动,并要求用户显式确认后才能继续。
可有的时候,问题在于实在是太容易出错了。比如下面这些荣登耻辱榜的错误信息例子:
不必要的错误信息
错误:
这估计是 Windows® XP 中最糟糕的错误信息了。它说该程序无法启动是因为 Windows 正在执行关机操作。对此用户什么也做不了,甚至是什么也不想做(要知道用户已经选择了关闭 Windows)。而且,为了显示这个错误信息,Windows 中断了关机操作。
问题:错误信息本身就是问题。除了无视这个错误信息以外,用户什么也做不了。
引发原因:报告一切错误情况,而不管用户的目的或其立场。
更正建议:不要报告那些用户并不关心的错误。
“成功的”错误信息
错误:
当卸载程序后,如果用户选择不立即重新启动 Windows 的话,则会出现此错误信息。但从用户的立场上来看,程序已经成功被卸载了。
问题:从用户的立场来看没有错误。除了无视这个错误信息以外,用户什么也做不了。
引发原因:从用户的立场来看,该任务已经成功完成,但从卸载程序的立场看来却是失败的。
更正建议:不要报告那些用户认为可以接受的情况。
完全无用的错误信息
错误:
用户知道这里发生了错误,但对于是什么错误或者应当如何处理却毫无头绪。而且,这一点也不 OK!
问题:错误信息并没有明确指出问题所在,用户也不知道需要做什么。
引发原因:大部分情况下是因为程序的错误处理机制很糟糕。
更正建议:为程序设计好的错误处理机制。
无法理解的错误信息
错误:
在这个示例中,问题表述得很明确,但是附加信息实在太令人困惑了。
问题:问题表述或解决方案令人无法理解。
引发原因:从代码的视角来解释错误,而不是站在用户的立场上。
更正建议:把错误信息的文字写得让你的目标用户能够轻易理解。提供用户实际能够执行的解决方案。为你的程序设计错误信息体验——千万别让程序员来撰写错误信息。
沟通过度的错误信息
错误:
在这个示例中,错误信息显然是打算解释解决问题的每个步骤。
问题:信息太多。
引发原因:信息过于具体,或者在一个错误信息里试图解释过于复杂的解决步骤。
更正建议:避免不必要的细节。并且,避免疑难解答过程。如果确实需要疑难解答,集中考虑最可能的解决方案,并通过指向帮助中的相关主题来解释其他的可能。
不必要的严厉的错误信息
错误:
程序找不到某个对象怎么也不像是灾难性的错误。就算它是灾难性的,为什么回答却是 OK?
问题:程序无须使用严厉或戏剧性的语气。
引发原因:问题来自于 bug,从程序的立场上来看或许是灾难性的。
更正建议:站在用户的立场上字斟句酌。
责备用户的错误信息
错误:
为什么要让用户觉得自己像个罪犯?
问题:错误信息的用语方式是在责备用户犯了错误。
引发原因:使用不敏感的词句,关注用户的行为而不是问题。
更正建议:关注问题,而不是引发问题的用户行为,必要时使用被动语态。
愚蠢的错误信息
错误:
在这个例子中,问题的表述实在是具有讽刺意味,而且没有提供任何解决方案。
问题: 错误信息的表述实在是愚蠢或者是无厘头的。
引发原因:创建错误信息却不留意其内容。
更正建议:精心编写错误信息,并经过专业写手的检查。在复查错误信息时,应当考虑上下文及用户当时的想法。
程序员错误信息
错误:
在这个例子中,错误信息指出了程序中存在的 bug,这只是对程序员来说才有意义。
问题:错误信息期望帮助程序开发人员在程序的发行版本中寻找遗留的 bug。但它对于用户来说没有任何意义和价值。
引发原因:程序使用普通的 UI 为自己提供信息。
更正建议:开发人员必须采用条件编译的方式处理所有此类消息,以确保其能自动从最终的发行版本中移除。不要把时间浪费在这些用户无法理解的错误信息上,因为程序员才是其唯一的受众。
糟糕的错误信息呈现
错误:
该示例存在多处常见的呈现错误。
问题:错误信息的所有细节呈现中都充满了错误。
引发原因:不了解、没有遵守错误信息设计规范。没有让专业写手及编辑来撰写或核查错误信息。
错误处理机制天生导致了这些错误很容易出现。这使得我们很难认识到,其实大多数错误信息都可以被提名到上面的那个耻辱榜上。
好的错误信息的性征
与之前那些反面例子相比,好的错误信息应当包含:
- 问题。描述出现的问题。
- 起因。解释为何出现该问题。
- 解决方案。提供解决方案,使用户能够修复问题。
除此之外,好的错误信息呈现方式应当具有下列特点:
- 相关性。错误信息所描述的问题是用户所关心的。
- 可执行性。出现该信息后,用户应当执行某操作或者改变其行为。
- 以用户为中心。错误信息描述的问题是就用户的行为或目的而言的,而不是代码。
- 简要。错误信息应当言简意赅,但又不至于表述不清。
- 清晰。错误信息语言平实,用户能够轻易理解问题和解决方案。
- 明确。错误信息在描述问题时使用了明确的语言、给出了相关对象的具体名称、位置及值。
- 礼貌。不应责备用户或让用户觉得自己很愚蠢。
- 罕见。偶尔出现。频繁出现的错误信息是设计不好的表现。
如果你设计的错误处理体验具备上述特征的话,你的程序就可以远离错误信息耻辱榜了。
避免不必要的错误信息
没有错误信息往往是最好的错误信息。许多错误信息经过更好的设计是可以避免出现的,而且经常会有更好的替代方案。一般说来,避免错误出现比报告错误要好。
最显而易见应当避免的错误信息就是用户什么也做不了的那类。如果用户通常只会忽略消息,什么也不做什么也不更改的话,就应当省略这个错误信息。
有些错误信息可以去掉是因为他们在用户看来没什么问题。例如,用户试图删除一个已经处于删除过程中的文件。虽然这从代码的立场上来说是一个意外情况,但用户并不认为这有什么错,因为达到了他们期望的结果。
错误:
该错误信息应当去除,因为在用户看来操作是成功的。
另一个例子,假设用户显式地取消了一个任务,在用户看来,下面的情况并不是错误。
错误:
这条错误信息也应当删去,因为在用户看来操作是成功的。
如果我们关注的是用户的目标而不是技术的话,有些错误信息也可以去掉。通过这样做,重新考虑究竟什么是错误。是用户的目标无法实现,还是你程序的能力无法满足它们?如果用户的行为在真实世界中行得通的话,在软件中也同样应该能行得通。
例如,假设在一个电子商务程序中,用户试图通过搜索功能来查找一个产品。然而,文本搜索没有得到任何匹配结果,而且他想要的产品已经脱销。从技术上说,这是一个错误,但程序不应该显示错误信息,而是可以:
- 继续搜索与查询条件最为接近的产品。
- 如果搜索存在明显的错误,自动推荐一个正确的查询。
- 自动处理一些常见问题,如拼写错误、多种拼写方式、单复数或动词形式不一致等。
- 指出产品何时有货。
只要用户的请求是合理的,作为一个设计良好的电子商务程序,其返回的结果也应当是合理的——而不是错误。
另一种避免错误信息的有效方法是从源头避免问题的发生。你可以通过下列方式避免错误:
- 使用带限制的控件。使用那些限制为只能输入有效值的控件。像列表、滑块、复选框、单选按钮、日期时间选择器等等控件都只接受那些有效的输入值,而文本框通常无法做到这一点,往往需要显示错误信息。不过,你也可以将文本框限定为只接受某些字符以及最大字符数。
- 使用带限制的交互。对于拖放操作来说,只允许用户拖放到有效目标上。
- 禁用控件与菜单项。如果用户很容易可以理解原因的话,可以禁用控件及菜单项。
- 提供合适的默认值。用户如果能接受默认值的话,就不那么容易造成输入错误。即使用户想进行修改,默认值也可以让用户知道应该使用什么样的输入格式。
- 能用就行。用户不太会在那些不必要的任务或者能自动完成的任务上犯错误。或者,即使用户出现了一些小的错误,但只要他们的意图足够清晰,问题仍可以自动解决。例如,你可以自动修正一些格式上的小问题。
提供必须的错误信息
有的时候你确实需要提供错误信息。用户犯了错误、网络或设备停止工作、对象不存在或已被修改、任务无法完成、程序存在 bug 等等。理想情况下,这些问题不会经常出现——例如,我们可以将软件设计为能够预防多种用户所犯的错误类型——但预防所有的错误是不现实的。当其中某种问题发生时,有用的错误信息能让用户迅速回到正常的状态。
通常认为错误信息是最差的用户体验,应当不惜一切代价避免。但是,准确地说,应该是使用户感到迷惑的才是最差的用户体验,应当不惜一切代价避免。有的,这种代价就是一则有用的错误信息。
比如说那些被禁用的控件。多数情况下,为什么禁用是显而易见的,所以禁用控件是避免错误信息的好办法。然而,如果控件被禁用的原因不那么明显呢?用户无法继续,而又没有任何反馈可以用来确定问题所在。于是,用户被卡在这里,要么推测出问题,要么寻求技术支持。在这种情况下,我们宁可让控件仍然可用,然后提供有用的错误信息。
错误:
下一步按钮为什么被禁用了?应该仍然让其可用,提供有用的错误信息,避免给用户带来迷惑。
如果你无法确定要不要提供错误信息,那么就先从撰写可能的错误信息开始。如果会导致用户执行某个操作或更改其行为,那么就提供此错误信息。反之,如果用户只是看完错误信息后什么也不做,就省略它。
设计好的错误处理
尽管整个过程充满了挑战,但如果程序没有提供好的错误处理机制,还是不一定就能写出好的错误信息。例如这条错误信息:
错误:
有时真的不知道问题在哪里,因为程序缺乏有效的错误处理机制。
当然有可能这是一个写得非常差劲的错误信息,不过这更主要反映出底层代码缺乏好的错误处理机制——没有针对该问题的信息。
为了创建明确的、可执行的、以用户为中心的错误信息,你程序的错误处理代码必须提供明确、高标准的错误信息:
- 应当为每个问题分配唯的错误码。
- 如果问题有多种可能的起因,无论如何,程序都应当确定到底是哪个原因引发了该问题。
- 如果问题附带有参数,那么参数也应当保留。
- 底层的问题应当在足够高的层次进行处理,以确保错误信息是从用户的立场来展示的。
好的错误信息不仅仅是用户界面的事情,也是软件设计的事情。好的错误信息体验是无法日后修补而成的。
疑难解答(以及如何避免它)
当一个问题存在多个可能的起因,而又通过同一个错误信息报告时,则需要疑难解答。
错误:
正确:
当用一个错误信息报告多个问题时,需要疑难解答。
下面的例子中,无法移动某项,因为它已经被移走或删除、或者访问被拒绝。如果程序程序能够简单地确定原因,何必让用户困扰究竟是哪个原因?
错误:
好吧,是哪个呢?用户此时会需要疑难解答。
如果程序能够确定访问是否被拒绝,就可以用更加明确的错误信息来报告这个问题。
正确:
有了明确的引发原因,疑难解答就不需要了。
仅当无法确定具体的起因时,才可在错误信息中同时描述多种原因。在这个例子中,程序很难确定它是被移走还是删除了,因此使用一条带有多个原因的错误信息在这里是允许的。不过,如果这并不是用户所关心的,比如,无法移动一个已被删除的文件。这种情况下,甚至都不需要错误信息。
处理未知错误
有些情况下,你确确实实不知道出了什么问题、什么原因以及如何解决。如果隐瞒错误不太合适的话,那么坦言信息不足要比提示一些可能不正确的问题、原因或解决方案要更好一些。
例如,如果你的程序出现了未处理的异常,下面的错误信息会较为合适:
如果无法隐瞒未知错误,最好就坦言信息不足。
另一方面,大多数情况下,如果很可能有帮助的话,就应当提供明确的、可操作的信息。
如果问题往往出在网络连接上的话,这条错误信息适用于未知错误。
确定合适的错误类型
如果强调的程度及措辞不同,有些问题可以分别表达为错误、警告或者信息。例如,假设在当前的 Windows Internet Explorer® 设置下,一个网页加载了一个未签名的 ActiveX 控件:
- Error. "This page cannot load an unsigned ActiveX control." (Phrased as an existing problem.)
- Warning. "This page might not behave as expected because Windows Internet Explorer isn't configured to load unsigned ActiveX controls." or "Allow this page to install an unsigned ActiveX Control? Doing so from untrusted sources may harm your computer." (Both phrased as conditions that may cause future problems.)
- Information. "You have configured Windows Internet Explorer to block unsigned ActiveX controls." (Phrased as a statement of fact.)
To determine the appropriate message type, focus on the most important aspect of the issue that users need to know or act upon. Typically, if an issue blocks the user from proceeding, you should present it as an error; if the user can proceed, present it as a warning. Craft the main instruction or other corresponding text based on that focus, then choose an icon (standard or otherwise) that matches the text. The main instruction text and icons should always match.
错误信息呈现
Most error messages in Windows programs are presented using modal dialog boxes (as are most examples in this article), but there are other options:
- In-place
- Balloons
- Notifications
- Notification area icons
- Status bars
- Log files (for errors targeted at IT professionals)
Putting error messages in modal dialog boxes has the benefit of demanding the user's immediate attention and acknowledgement. However, this is also their primary drawback if that attention isn't necessary.
Do you really need to interrupt users so that they can click the Close button? If not, consider alternatives to using a modal dialog box.
Modal dialogs are a great choice when the user must acknowledge the problem immediately before continuing, but often a poor choice otherwise. Generally, you should prefer to use the lightest weight presentation that does the job well.
避免沟通过度
Generally, users don't read, they scan. The more text there is, the harder the text is to scan, and the more likely users won't read the text at all. As a result, it is important to reduce the text down to its essentials, and use progressive disclosure and Help links when necessary to provide additional information.
There are many extreme examples, but let's look at one more typical. The following example has most of the attributes of a good error message, but its text isn't concise and requires motivation to read.
Incorrect:
This example is a good error message, but it overcommunicates.
What is all this text really saying? Something like this:
Correct:
This error message has essentially the same information, but is far more concise.
By using Help to provide the details, this error message has an inverted pyramid style of presentation.
For more guidelines and examples on overcommunicating, see User Interface Text.
If you do only eight things...
- Design your program for error handling.
- Don't give unnecessary error messages.
- Avoid user confusion by giving necessary error messages.
- Make sure the error message gives a problem, cause, and solution.
- Make sure the error message is relevant, actionable, brief, clear, specific, courteous, and rare.
- Design error messages from the user's point of view, not the program's point of view.
- Avoid involving the user in troubleshooting—use a different error message for each detectable cause.
- Use the lightest weight presentation method that does the job well.