我在测试中没有发现 bug,所以零碎没有 bug,对吧?
可怜的是,大规模的软件太简单,无论多少测试都无奈做到没有 bug。你无奈对用户应用应用程序的所有不同形式进行测试。因而,了解应用程序中谬误和异样的区别是十分重要的,同时要理解解决它们的正确办法,以便你能够采取被动的形式为开发团队和终端用户提供衰弱的应用程序。
测试的局限性
即便应用最彻底的测试过程,依然只是在测试特定的状况,并且蕴含了本人的想法在其中。
设想一下,忽然有成千上万的用户以你没有想到的形式应用你的应用程序——他们简直必定会碰到你在测试时没有碰到的货色。
如何正确处理应用程序中的谬误
简略地说,bug 能够导致谬误和异样。谬误和异样是有不同含意的术语。
次要的问题应该是如何更好地解决这些谬误和异样,使它们不会产生负面结果。
首先,让咱们看看一些定义,以及为什么这些区别很重要。
谬误和异样——有什么区别?
一些编程语言有它们本人的谬误和异样定义,然而我想定义它们的区别。
谬误
无奈优雅地复原 / 持续的编程谬误,通常须要开发人员染指并批改代码来进行修复。有时能够将谬误转换为异样,以便在代码中解决它们。
通过简略查看能够防止谬误,如果简略查看不能满足要求,谬误还能够转化为异样,以便应用程序可能优雅地解决这种状况。
异样
利用特定语言的语义,并在产生异样时示意。异样能够被捕捉和抛出,以便代码能够复原和解决这种状况,而不进入谬误状态。
能够抛出和捕捉异样,以便应用程序可能失常复原或持续。还能够记录未解决的异样 (即谬误),以便开发人员查看它们以修复底层谬误。
示例# 1
用户谬误——用户输出谬误数据,也不须要异样解决,但仍可能导致谬误 / 不可复原状态。代码应该进行简略的查看,以避免产生这种状况。应该应用前端和后端验证,对于本例,只抛出一个异样作为“最初的进攻”。
示例# 2
文件无奈关上并抛出 FileLoadException 或 FileNotFoundException。这是一种非凡状况,不应该毁坏应用程序。应用程序应该可能解决这种状况,因为这种状况可能因为许多起因而产生,因而,你必须预期到这种状况。
该出错的还是会出错……至多一次
“所以……如果我捕捉到每个异样,我的代码就不会出错了,对吧?”
正如我后面提到的,并非所有谬误都会导致异样。这个论断的次要问题是你不晓得哪里出了问题。你的代码可能存在许多问题,因为捕捉异样而对其不做任何解决,你会失落这些信息。
不要只是捕获每个异样,而后持续,就像什么都没有产生过一样。捕捉块的目标是在肯定状况下进行解决。
不要做什么——把他们捕捉起来。
如何编写应用程序来复原本人
抛出和捕捉异样是让应用程序自行复原并避免它运行到谬误状态的好办法。
如果你晓得可能会抛出哪一种类型的异样,最好在 catch 块中显式地显示,因为每种不同类型的异样都将意味着代码因为不同的起因而进行。
异样类型要具体,这样就能够向用户提供反馈,并在确切晓得失败的起因后更优雅地解决其余状况。
为什么指定要捕获哪种类型的异样很重要?
某些异样可能毁坏数据或以意外的形式运行,这取决于你的程序如何持续运行。这将导致应用程序呈现谬误。
如果你确切地晓得产生了哪种异样,那么你应该晓得要依照哪些步骤进行复原。或者,如果无奈复原,你应该晓得如何优雅地解决这种状况。
那么,它能复原吗? 在很多状况下,异样具备足够的信息来晓得产生了什么谬误,并且在 catch 块中,你有时能够从谬误状态中复原。能够通过修复一些数据、从新获取数据或甚至要求用户再试一次。
你能够捕捉异样,但有时应用程序依然无奈持续运行,因为它所依赖的数据曾经以不可复原的形式被损坏,或者它冀望数据采纳不同的格局。
示例
数组上的 OutOfRangeException 异样? 一个程序如何能力复原? 这是一个将谬误转化为异样的例子。你的应用程序冀望数据以某种形式呈现,但这并没有产生。尽管复原并不总是可能,但当初可能不进入谬误状态并优雅地解决这种状况。如果将此记录下来,开发人员能够通过在拜访数组之前增加一些简略的查看或更改拜访它的形式来修复此问题。
如何解决未解决的异样
有一些你意想不到的异样,通常示意代码中的谬误。你能够记录那些没有被代码捕捉的未解决的异样,因为大多数语言都提供了这样做的办法。任何未解决的异样都示意谬误。你的代码没有预料到这一点,因而无奈失常复原或解决这种状况。
将它们记录下来是一个好主见,这样就能够修复。这样,谬误就不会常常抛出异样。如果它们真的产生了,你想要理解它们,这样你就能够捕捉它们并解决它们。
谬误日志
谬误日志能够帮忙捕捉这些谬误。有一个能够查看这些日志谬误 / 异样的中央是调试的要害,也是确定何时修复什么问题的优先级。
此外,你也不心愿依赖于屏幕截图和曾经丧气的用户提供的更多信息。谬误日志记录还能够使你的团队在呈现谬误时可能积极主动地分割受影响的用户。这是为了让他们晓得你正在解决问题,这不仅会促成你的客户关系,而且你还能够在其余用户遇到谬误之前修复谬误。
示例
代码中产生多个不正确的账单费用的谬误通常比无奈显示特定详细信息页面的谬误更重要,即便详细信息页面谬误产生得更频繁。
最终,你心愿应用程序遇到的异样尽可能少,然而当它遇到异样时,你心愿理解它。只有 1% 的用户报告谬误,所以还有很多谬误依然存在。
解决局部问题
编写一些代码将异样和堆栈保留到文件中,或者通过电子邮件发送,以便在产生谬误时失去告诉,这可能是局部解决方案。
示例
一个用户会遇到上千个异样。100 个用户也遇到了较少产生的谬误。哪个更重要? 在不晓得谬误细节的状况下,影响更多用户的谬误更重要。
应用异样的堆栈应该有助于定位谬误可能呈现的地位,并且你应该可能从新生成它或浏览代码以了解那里出了错。
有时这还不够,问题须要进一步考察。如果产生这种状况,在记录异样之前向异样增加更多信息,包含上下文特定细节 (例如帐户 id 或特定对象状态),这些信息将容许你在本地从新生成谬误。
是时候修改谬误了
当初,你应该曾经捕捉了所有的谬误和异样,并记录未解决的谬误……当初该怎么办呢?
依据应用程序的规模,谬误告诉中的乐音是一个问题。你能够应用电子邮件过滤 /grep 做一些聪慧的事件,它能够分组谬误并拆散到不同的文件夹 / 文件中。这可能有所帮忙,但只是对乐音问题的局部解决方案。
几年前,我集体也这么做过,但很快意识到这只是一个局部的解决方案,起因有很多。问题是,我依然不晓得哪些谬误对用户的影响最大。我关注的是那些抛出的谬误,而不是那些对应用程序 / 用户体验最无害的谬误——正因为如此,我从未真正分明地晓得哪里出了问题。
我无奈看到产生了什么,但必须运行手动查问能力弄清楚,这十分耗时。
对于大型软件,总是会抛出谬误和异样。正确地处理错误将有助于将你定义为一个软件团队,并围绕异样和谬误创立更好的过程。
好的应用程序蕴含能够在可能的状况下从异样中复原的代码。解决和记录异样对软件的运行状况十分重要!
欢送关注我的公众号,如果你有喜爱的外文技术文章,能够通过公众号留言举荐给我。