我经常遇到应用程序,包括来自 Microsoft 的应用程序,它们的开发人员懒得告诉用户真正发生了什么以及应用程序崩溃的原因。
例子:
- “出问题了”
- “未知/未识别的错误”
- “安装中止”
- “申请无法继续”
这些不是断章取义的文本,而是您一生中至少见过一次的完整消息,除了您仍然可以在末尾添加“...稍后再试”。仅此而已。
这里还有一些问题,错误处理的一切都非常糟糕。不是技术上的,而是逻辑上的。可以给这篇文章的链接以帮助新人。
例如,为了简单起见,让我们以一个写入文件的控制台应用程序为例。
// плохой код
static void Main(string[] args)
{
Console.Write("Введите имя файла для записи: ");
string path = Console.ReadLine();
try
{
File.WriteAllText(path, "Hello World!");
Console.WriteLine("Файл записан!");
}
catch
{
Console.WriteLine("Что-то пошло не так!");
}
}
可以根据您的判断来描述答案:
- 如何通知用户错误:界面、日志、其他方式。
- 错误的逻辑类型:致命等。
- 应该在错误文本中放置什么:需要堆栈跟踪的位置,不需要的位置。
一般来说,我们需要一个问题的答案:桌面应用程序的新手开发人员应该如何处理异常,以便用户在异常发生时不会感到困惑?
(不会有自我反应,我也对这个不好)
- 相关问题:为用户生成错误消息的正确方法是什么?
对于简单的程序 - 您可以创建一个自清洁日志窗口,该窗口位于设置中的某处。您可以使用 StringBuilder 优化并仅在打开时输出。
对于复杂的商业程序(或“摸索”用户的程序),日志窗口应该在手边,可能在某个选项卡上或通过单击单独窗口中的按钮。是的,而且 MessageBox 的严重错误并没有被取消。
相当一部分用户不是无脑用户,如果出现任何问题,他们能够看到日志窗口中的最后一行,并且伴随您的程序的技术支持和管理员会为您唱颂歌,因为它不止一次发生过重要程序界面很差,几乎没有日志文件,然后由于部分用户无法连接,半数组织处于空闲状态,主管理员也搞不清楚是哪里出了问题。每天有成百上千的工时付诸东流,因为 该程序没有愚蠢的多行消息框,它会愚蠢地显示连接日志。
这是生活中的一个例子。
如果日志级别太多,日志窗口中的消息越多越好(同样,不是针对最终用户,而是针对稍后将处理问题的人,他们肯定会是一个或另一个)。
至于堆栈跟踪,如果应用程序处于调试模式,那么它也可以输出到接口日志中。
在 Promise 中,一切都在界面日志中,甚至是成功的操作。
关于日志文件 - 只有问题和启动过程(一点遥测不会有伤害),问题不是内部问题,而是与外部接口交互有关:tcp / udp 连接,文件访问拒绝,数据输入错误等......
在 try-catch 中明确捕获预期错误的地方(例如,服务器不可用) - 向用户显示错误,并提供可能的解决方案,您假设可能存在错误但出于未知原因的云 - 另外堆栈跟踪到日志文件。
到其他方法- syslog 服务器。
另一种选择是从父进程(管道)接收详细日志的子进程,并且在父进程崩溃的情况下,将最近操作/错误的日志输出并记录到文件中。现在这种方法可能有更高级的替代方案。
简而言之,应始终显示干扰工作的错误。
因为 当用户(包括管理员的技术支持)遇到问题时,他会根据以下算法进行操作:
在第 0-3 点 - 界面中的一切都很简单。
3-5 - 消息框就足够了。
4-9 - 查看活动日志。
6-9 - 如果用户不是用户,但非常热衷于技能,他已经在阅读日志文件并查找在哪个阶段不能正常工作,然后需要一些详细说明以及潜在的列表可能的解决方案的问题。它可以达到平庸,例如,如果您的应用程序是服务器并且没有与之连接 - 说明应该有一个选项:“不要忘记在路由器中转发端口,添加防火墙/防病毒例外。”
9-10 - 已经有一个日志文件将发送给您。(我不会说转储,不是我的水平)
蛋糕上的樱桃第11号-
если с ходу не разберётесь, то придётся выкатывать обновления исключительно для того, чтобы программа писала дополнительную инфу (с стектрейсами и свойствами классов) в лог файл. Более того, придётся это делать для старой версии, которая официально более не поддерживается, но т.к. её купили и ей пользуются...可以仅根据有关程序目的和目标对象的数据更详细地说。
如果他们要求一个完善的复杂程序,只要用户看不到有关错误的信息并且不需要自己解决任何问题,并且所有这些都是离线的,没有注册和短信,那么需要两件事之一:技术支持军队或者吐槽这个未完成的任务管理器。大多数情况下,这是一位经理,除了 iPhone 之外,没有使用任何东西,并且在第一次尝试输入错误的密码时,他跑去要求技术支持(以便一切对他“有效”),向管理员,并诋毁程序员......
一个好的程序不是一个在优美的界面下隐藏错误的程序,而是一个为解决错误提供更多选择的程序(越方便越好)。问题过去、现在和将来都会无处不在。主要是能够解决它们。最后,选择那些可以自行解决问题的程序,而不是那些您等待一周等待票到达队列中合适的人以便他说重新排列 Windows 的程序。
在回答这个问题时:
Что делать с исключениями новичку-разработчику десктопного приложения, чтобы пользователь не растерялся при его возникновении?我想说的是:如果您希望用户能够自己解决问题(当然,如果这不是代码中的错误,而是外部资源的问题),更多的检查是更好,例如:“服务器不可用,端口繁忙,文件损坏等......”,不应该跳出堆栈跟踪,而是在它们发生之前进行检查,在日志窗口中提供更详细的信息,甚至当一切正常时,例如“连接成功,文件(url)在T秒内从服务器下载,格式.***,句柄打开/关闭,文件(C:\**1)读取,文件(C:\ **2) 读取,文件 (C:\**3) 读取”。
有什么东西载着我,因为。当你想说“好吧,看看日志窗口中的最后一行,我把它作为专家给你拿出来”时,就像一个程序员一样痛苦,就像管理员一样,当程序没有以任何方式通知时,但是你需要修复它。人们工作,作为用户,当我想为自己解决问题时,应用程序是一个黑盒子。希望我没有胡说八道。
在我看来,这是错误的,但是,我可以理解为什么会这样做。如果向用户显示错误消息,应注意确保他可以理解:翻译成他所说的语言,以简单用户可以理解的术语解释所有内容,等等。对于典型的
MessageBox.Show(ex.Message),这通常不会被观察到。因此,合乎逻辑的解决方案是忽略它,将消息替换为无意义的消息,并建议高级用户如果对真正的错误消息非常感兴趣,请深入研究日志。另一个原因可能是商业模式。如果程序是免费的或廉价的,而开发者的主要收入来自付费支持,那么开发者不向用户提供信息以自行解决问题,而是显示一个不露面的错误代码并提供更有利可图联系支持。
如果你不是微软,我仍然建议不要遵循这种方法,请参阅下面我的方法。
这几乎总是一种反模式。可以忽略异常,但在这种情况下,如果需要,屏幕上不应显示任何内容。当某些事情真正“出错”时,您至少应该记录它。
"Произошла ошибка: "+ex.GetType().ToString()+ex.Message。ex.ToString()(即使用堆栈)。ex.ToString()。使用这种方法,用户可能无法理解所显示的信息,但对我来说,接受这一点比通过隐藏信息在用户的轮子中加入辐条更好。与 Web 应用程序不同,在桌面应用程序中不存在意外发布秘密数据的风险,因为该程序仅适用于用户已经可用的数据。
如果用户是程序员,您也可以在屏幕上显示调用堆栈,但不是在标准 MessageBox 中,而是自己制作,堆栈放置在单独的可滚动字段中 - 如下所示:
我认为没有理由区分致命和非致命。真正致命的问题,例如访问冲突,仍然无法通过标准方式处理。所有其余的都需要处理,即使是那些是错误的结果。强烈建议不要因为原始 NRE 而导致流程崩溃和标准的“提交给 Microsoft...”对话框。在这种情况下,所有未保存的用户数据都将丢失,这大大超过了数据损坏的理论风险,同时继续处理该错误。而且从发送到微软,它仍然没有用,因为他们不关心我们文件中的错误。
注意力!由于该问题被标记为桌面,因此所有建议仅适用于桌面应用程序。对于 Web 应用程序,方法应该完全不同。