Node.js 中的错误处理综合指南
每个应用程序中都会发生错误。开发人员必须决定:您是否编写代码来处理错误?抑制它?通知用户?向团队报告?在本文中,我将引导您了解 JavaScript 错误系统的各个方面。我将向您展示如何处理错误,并讨论适用于实际场景的适当选择。
如果您编写的程序不是 “Hello world” 程序,那么您可能对编程中的错误概念很熟悉。它们是代码中的错误,通常称为“错误”,会导致程序失败或行为异常。与某些语言(如 Go 和 Rust)不同,在每一步都被迫与潜在错误交互,在 JavaScript 和 Node.js 中没有连贯的错误处理策略,则可能会过得去。
但是,情况并非必须如此,因为一旦您熟悉用于创建、交付和处理潜在错误的模式Node.js错误处理就会非常简单。本文旨在向您介绍这些模式,以便您可以通过在将应用程序部署到生产环境之前发现潜在错误并适当地处理它们来使您的程序更加健壮!
Node.js 中的错误是对象的任何实例。常见示例包括内置错误类,例如 、 和 。还可以通过扩展基对象、内置错误类或其他自定义错误来创建用户定义的错误。以这种方式创建错误时,应传递描述错误的消息字符串。可以通过对象上的属性访问此消息。该对象还包含 a 和 a 属性,分别指示错误的名称和代码中创建错误的点。ErrorReferenceErrorRangeErrorTypeErrorURIErrorEvalErrorSyntaxErrorErrormessageErrornamestack
JavaScript
拥有对象后,您可以将其传递给函数或从函数返回它。您也可以使用 it,这会导致对象成为异常。一旦你抛出一个错误,它就会在堆栈中冒泡,直到它被捕获到某个地方。如果你没有捕获它,它就会变成一个未捕获的异常,这可能会导致你的应用程序崩溃!ErrorthrowError
从 JavaScript 函数传递错误的适当方式因函数是执行同步操作还是异步操作而异。在本节中,我将详细介绍从 Node.js 应用程序中的函数传递错误的四种常见模式。
函数传递错误的最常见方式是抛出错误。当你抛出一个错误时,它就会变成一个异常,需要使用一个块来捕获堆栈中的某个地方。如果允许错误在堆栈中冒泡而不被捕获,则它将成为 ,这会导致应用程序提前退出。例如,如果内置方法的 string 参数不是有效的 JSON 对象,则会引发错误。try/catchuncaughtExceptionJSON.parse()
JavaScript
要在函数中使用这种模式,您需要做的就是在错误实例之前添加关键字。这种错误报告和处理模式对于执行同步操作的函数来说是惯用的。throw
JavaScript
由于其异步性质,Node.js 在其大部分错误处理中大量使用回调函数。回调函数作为参数传递给另一个函数,并在该函数完成其工作时执行。如果您编写 JavaScript 代码的时间长短,您可能知道回调模式在整个 JavaScript 代码中被大量使用。
Node.js 在其大多数异步方法中使用错误优先回调约定,以确保在使用操作结果之前正确检查错误。此回调函数通常是启动异步操作的函数的最后一个参数,当发生错误或操作提供结果时,将调用一次。其签名如下所示:
JavaScript
第一个参数保留用于 error 对象。如果在异步操作过程中发生错误,则可以通过参数访问该错误,并且该错误将为 但是,如果未发生错误,则为 或 ,并且将包含操作的预期结果。可以通过使用内置方法读取文件内容来演示此模式:errresultundefined.errnullundefinedresultfs.readFile()
JavaScript
如你所见,该方法需要一个回调函数作为其最后一个参数,该参数遵循前面讨论的 error-first 函数签名。在这种情况下,该参数包含未发生错误时读取的文件内容。否则,它是 ,并且参数中填充了一个 error 对象,其中包含有关问题的信息(例如,找不到文件或权限不足)。readFile()resultundefinederr
通常,使用此回调模式进行错误传递的方法无法知道它们产生的错误对应用程序有多重要。它可能很严重,也可能是微不足道的。错误不是自己决定,而是发送给您处理。在尝试访问操作结果之前,始终检查错误,从而控制回调函数内容的流,这一点很重要。忽略错误是不安全的,在检查错误之前,您不应该相信 的内容。result
如果你想在自己的异步函数中使用这种错误优先的回调模式,你需要做的就是接受一个函数作为最后一个参数,并按如下所示的方式调用它:
JavaScript
此函数的任何调用方都需要传递回调函数来访问其结果或错误。请注意,如果 callback 参数不是函数,则会发生运行时异常。square
JavaScript
您不必直接在回调函数中处理错误。你可以通过将其传递给不同的回调来将其传播到堆栈中,但请确保不要从函数内部抛出异常,因为它不会被捕获,即使你将代码括在一个块中。异步异常是不可捕获的,因为周围的块在执行回调之前退出。因此,异常将传播到堆栈的顶部,导致应用程序崩溃,除非已注册处理程序,这将在后面讨论。try/catchtry/catchprocess.on(\’uncaughtException\’)
JavaScript
Promise 是在 Node.js 中执行异步操作的现代方式,现在通常比回调更受欢迎,因为这种方法具有更好的流程,与我们分析程序的方式相匹配,尤其是与模式相匹配。任何利用 error-first 回调进行异步错误处理的 Node.js API 都可以使用内置方法转换为 promise。例如,以下是如何使该方法使用 promises:async/awaitutil.promisify()fs.readFile()
JavaScript
该变量是 的 promisified 版本,其中 promise 拒绝用于报告错误。这些错误可以通过链接方法捕获,如下所示:readFilefs.readFile()catch
JavaScript
您还可以在函数中使用 promisified API,如下所示。这是在现代 JavaScript 中使用 promise 的主要方式,因为代码读起来像同步代码,并且可以使用熟悉的机制来处理错误。在异步方法之前使用非常重要,这样在函数恢复执行之前 promise 被 settle (fulfilled 或 rejected)。如果 promise 拒绝,则表达式将抛出被拒绝的值,该值随后被捕获到周围的块中。asynctry/catchawaitawaitcatch
JavaScript
您可以通过从函数返回 promise 并将函数代码放在 promise 回调中,在异步函数中使用 promise。如果出现错误,则使用 object.否则,将 promise 与 result 一起访问,以便它可以在链式方法中访问,或者在使用 .rejectErrorresolve.thenasync/await
JavaScript
在处理可能产生多个错误或结果的长时间运行的异步操作时,可以使用的另一种模式是从函数返回 EventEmitter 并针对成功和失败情况发出事件。此代码的示例如下所示:
JavaScript
该函数返回一个新的事件发射器,该发射器报告异步操作中的成功和失败事件。该函数递增变量并每秒发出一个事件,如果能被 整除,则发出一个事件。当达到 10 时,将发出一个事件。此模式允许在结果到达时流式传输结果,而不是等到整个操作完成。emitCount()countsuccesserrorcount4countend
下面介绍如何侦听和响应函数发出的每个事件:emitCount()
JavaScript
从上图中可以看出,每个事件侦听器的回调函数在事件发出后立即独立执行。该事件是 Node.js 中的一种特殊情况,因为如果没有侦听器,Node.js进程将崩溃。您可以注释掉上面的事件侦听器并运行程序以查看会发生什么。errorerror
使用内置的 error 类或对象的泛型实例通常不够精确,无法传达所有不同的 error 类型。因此,有必要创建自定义错误类,以更好地反映应用程序中可能发生的错误类型。例如,您可以有一个类来表示验证用户输入时发生的错误,类用于数据库操作,用于超过分配的超时的操作,等等。ErrorValidationErrorDatabaseErrorTimeoutError
扩展对象的自定义错误类将保留基本的错误属性,例如 、 和 ,但它们也可以具有自己的属性。例如,可以通过添加有意义的属性来增强 a,例如导致错误的 input 部分。从本质上讲,您应该包含足够的信息,以便错误处理程序正确处理错误或构建自己的错误消息。ErrormessagenamestackValidationError
以下是在 Node.js 中扩展内置对象的方法:Error
JavaScript
上面的类是应用程序的一般错误,而该类表示验证用户输入时发生的任何错误。它继承自该类,并使用一个属性对其进行扩充,以指定触发错误的输入。您可以在代码中使用自定义错误,就像处理普通错误一样。例如,您可以:ApplicationErrorValidationErrorApplicationErrorcausethrow
JavaScript
该关键字应用于检查特定的错误类型,如上所示。不要使用错误的名称来检查类型,如 ,因为如果错误派生自 .instanceoferr.name === \’ValidationError\’ValidationError
区分 Node.js 应用程序中可能发生的不同类型的错误是有益的。通常,错误可以分为两大类:程序员错误和操作问题。函数的参数错误或不正确是第一种问题的示例,而处理外部 API 时的瞬态故障则属于第二类。
操作错误主要是在应用程序执行过程中可能发生的预期错误。它们不一定是 bug,而是可能破坏程序执行流程的外部环境。在这种情况下,可以理解并适当处理错误的全部影响。Node.js 中的一些操作错误示例包括:
- API 请求由于某种原因(例如,服务器关闭或超出速率限制)而失败。
- 数据库连接丢失,可能是由于网络连接故障。
- 操作系统无法满足您打开或写入文件的请求。
- 用户向服务器发送无效的输入,例如无效的电话号码或电子邮件地址。
这些情况不是由于应用程序代码中的错误而引起的,但必须正确处理它们。否则,它们可能会导致更严重的问题。
程序员错误是程序逻辑或语法中的错误,只能通过更改源代码来纠正。这些类型的错误无法处理,因为根据定义,它们是程序中的 Bug。程序员错误的一些示例包括:
- 语法错误,例如无法关闭大括号。
- 当您尝试执行非法操作时,例如对不匹配类型的操作数执行操作,则会出现类型错误。
- 调用函数时参数错误。
- 当您拼错变量、函数或属性名称时出现引用错误。
- 尝试访问数组末尾之外的位置。
- 无法处理操作错误。
操作错误大多是可预测的,因此必须在开发过程中预测和考虑它们。从本质上讲,处理这些类型的错误涉及考虑操作是否会失败、为什么会失败以及如果失败会发生什么。让我们考虑一些在 Node.js 中处理操作错误的策略。
在许多情况下,适当的操作是停止程序的执行流程,清理任何未完成的进程,并将错误报告到堆栈中,以便可以适当地处理它。当发生错误的函数位于堆栈的较后位置,以至于它没有足够的信息来直接处理错误时,这通常是解决错误的正确方法。可以通过本文前面讨论的任何错误传递方法报告错误。
对外部服务的网络请求有时可能会失败,即使请求完全有效。这可能是由于暂时性故障造成的,如果出现网络故障或服务器过载,则可能会发生暂时性故障。此类问题通常是短暂的,因此您可以重试请求几次,直到成功或达到最大重试次数,而不是立即报告错误。首先要考虑的是确定是否适合重试请求。例如,如果初始响应 HTTP 状态代码为 500、503 或 429,则最好在短暂延迟后重试请求。
您可以检查响应中是否存在 Retry-After HTTP 标头。此标头指示在发出后续请求之前要等待的确切时间。如果 header 不存在,则需要延迟后续请求,并逐步增加每次连续重试的延迟。这被称为指数退避策略。您还需要确定最大延迟间隔以及在放弃之前重试请求的次数。此时,您应该通知调用方目标服务不可用。Retry-After
在处理来自用户的外部输入时,应假定默认情况下输入是错误的。因此,在开始任何进程之前要做的第一件事是验证输入并及时向用户报告任何错误,以便可以更正和重新发送。在传递客户端错误时,请确保包含客户端构建对用户有意义的错误消息所需的所有信息。
在出现无法恢复的系统错误的情况下,唯一合理的操作过程是记录错误并立即终止程序。如果异常在 JavaScript 层无法恢复,您甚至可能无法正常关闭服务器。此时,系统管理员可能需要调查问题并修复它,然后程序才能再次启动。
由于它们的性质,无法处理程序员错误;它们是由于代码或逻辑损坏而引起的程序错误,随后必须纠正。但是,您可以采取一些措施来大大降低它们在应用程序中出现的频率。
TypeScript 是 JavaScript 的强类型超集。其主要设计目标是静态识别可能是错误的构造,而不会造成任何运行时损失。通过在项目中采用 TypeScript(使用最严格的编译器选项),您可以在编译时消除一整类程序员错误。例如,在对错误进行事后分析后,估计 Airbnb 代码库中 38% 的错误可以通过 TypeScript 来预防。
当您将整个项目迁移到 TypeScript 时,代码库中不应再存在 “ is not a function”、语法错误或引用错误等错误。值得庆幸的是,这并不像听起来那么令人生畏。将整个 Node.js 应用程序迁移到 TypeScript 可以逐步完成,以便您可以立即开始在代码库的关键部分获得回报。如果您打算一次性执行迁移,您也可以采用 ts-migrate 之类的工具。undefined
许多程序员错误是由于传递错误的参数而导致的。这些错误可能不是由于明显的错误,例如传递字符串而不是数字,还可能是由于细微的错误,例如当函数参数的类型正确但超出函数可以处理的范围时。当程序正在运行并以这种方式调用函数时,它可能会以静默方式失败并产生错误的值,例如 .当最终注意到故障时(通常是在经历了几个其他函数之后),可能很难找到它的来源。NaN
当问题可以在本地处理时,您可以通过引发错误或返回特殊值(例如 , 或 )来定义其行为来处理错误的参数。前者是 使用的方法,如果要解析的字符串不是有效的 JSON,则会引发异常,而该方法就是后者的一个示例。无论您选择哪种方式,请确保记录函数如何处理错误,以便调用方知道会发生什么。nullundefined-1JSON.parse()SyntaxErrorstring.indexOf()
就其本身而言,JavaScript 语言并不能帮助您发现程序逻辑中的错误,因此您必须运行该程序以确定它是否按预期工作。自动化测试套件的存在使您更有可能发现并修复各种程序员错误,尤其是逻辑错误。它们还有助于确定函数如何处理非典型值。使用测试框架(如 Jest 或 Mocha)是开始对 Node.js 应用程序进行单元测试的好方法。
未捕获的异常和未处理的 Promise 拒绝分别是由未能捕获引发的异常和 Promise 拒绝导致的程序员错误引起的。当应用程序中某处引发的异常在到达事件循环之前未被捕获时,将发出该事件。如果检测到未捕获的异常,应用程序将立即崩溃,但您可以为此事件添加处理程序以覆盖此行为。事实上,许多人将此作为吞下错误的最后手段,以便应用程序可以继续运行,就像什么都没发生一样:uncaughtException
JavaScript
但是,这是对此事件的错误使用,因为存在未捕获的异常表明应用程序处于未定义状态。因此,尝试正常恢复而不从错误中恢复被认为是不安全的,并可能导致进一步的问题,例如内存泄漏和套接字挂起。处理程序的适当用途是清理任何分配的资源,关闭连接,并在退出进程之前记录错误以供以后评估。uncaughtException
JavaScript
同样,当被拒绝的 Promise 未使用块处理时,将发出该事件。与 不同,这些事件不会导致应用程序立即崩溃。但是,未处理的 promise 拒绝已被弃用,并且可能会在未来的 Node.js 版本中立即终止该进程。您可以通过事件侦听器跟踪未处理的 promise 拒绝,如下所示:unhandledRejectioncatchuncaughtExceptionunhandledRejection
JavaScript
您应该始终使用进程管理器来运行服务器,该进程管理器将在崩溃时自动重新启动它们。一个常见的是 PM2,但你也有 OR 在 Linux 上,Docker 用户可以使用它的重启策略。一旦到位,Reliable Service 将几乎立即恢复,并且您仍将拥有未捕获异常的详细信息,以便及时调查和更正。您可以通过运行多个进程并使用负载均衡器来分发传入请求来更进一步。这将有助于防止其中一个实例暂时丢失时停机。systemdupstart
如果没有针对正在运行的应用程序的强大日志记录策略,任何错误处理策略都是不完整的。发生故障时,通过记录尽可能多的有关问题的信息来了解故障发生的原因非常重要。集中这些日志可以轻松全面了解您的应用程序。您将能够对错误进行排序和筛选,查看主要问题,并订阅警报以获取新错误的通知。
Honeybadger 提供了监控生产应用程序中发生的错误所需的一切。请按照以下步骤将其集成到您的 Node.js 应用程序中:
用于安装软件包:npm
命令
导入库并使用您的 API 密钥对其进行配置,以开始报告错误:
JavaScript
您可以通过调用该方法报告错误,如以下示例所示:notify()
JavaScript
有关 Honeybadger 如何与 Node.js Web 框架集成的更多信息,请参阅完整文档或查看 GitHub 上的示例 Node.js/Express 应用程序。
类(或子类)应始终用于传达代码中的错误。从技术上讲,你可以在 JavaScript 中做任何事情,而不仅仅是对象,但不建议这样做,因为它大大降低了错误的有用性,并且容易出错处理错误。通过持续使用对象,您可以可靠地期望访问或位于处理或记录错误的位置。您甚至可以使用与发生错误的上下文相关的其他有用属性来扩充 error 类。ErrorthrowErrorErrorerror.messageerror.stack
操作错误是不可避免的,应该在任何正确的程序中加以考虑。大多数情况下,应采用可恢复的错误策略,以便程序可以继续平稳运行。但是,如果错误足够严重,则终止程序并重新启动它可能是合适的。如果出现此类情况,请尝试正常关闭,以便程序可以以干净状态再次启动。
程序员错误无法处理或恢复,但可以通过自动化测试套件和静态类型工具来缓解。在编写函数时,定义错误参数的行为,并在检测到后采取适当的措施。允许程序在检测到 or 时崩溃。不要试图从此类错误中恢复!uncaughtExceptionunhandledRejection
使用错误监控服务(如 Honeybadger)来捕获和分析您的错误。这可以帮助您显著提高调试和解决的速度。
如果您的目标是编写优秀且可靠的软件,那么正确的错误处理是不可协商的要求。通过使用本文中描述的技术,您将顺利实现这一目标。
感谢您的阅读,祝您编码愉快!
JS常见错误和解决方法集锦
hello大家好,很多同学使用webfunny前端监控系统也有一段时间了,发现在js错误统计功能中遇到了一些问题,不知道该如何下手解决。前端监控平台只是一个辅助工具(并非神器),正常情况下它们只能搜集问题,并以更好的方式展示给我们看,并不能够直接解决问题,所以还是需要我们根据错误信息来处理错误。今天我将为大家总结一下前端开发中常见的问题,以及解决方案。
运行时错误,会有很多种类型,分别为:
1. SyntaxError:语法错误;
这个一般是新手开发者容易犯得的错误,比如变量名的命名不规范,给关键字进行赋值,花括号没有成对儿出现等等。这些错误很容易在开发的时候就被发现,
常见的错误信息如: SyntaxError: Invalid or unexpected token;Uncaught SyntaxError: Unexpected token =;Uncaught SyntaxError: Unexpected number;
常见代码如下:
2. Uncaught ReferenceError:引用错误
引用一个不存在的变量时发生的错误。将一个值分配给无法分配的对象,比如对函数的运行结果或者函数赋值。
常见错误信息如:Uncaught ReferenceError: xxx is not defined;Uncaught ReferenceError: Invalid left-hand side in assignment;
3. RangeError:范围错误
RangeError是当一个值超出有效范围时发生的错误。主要的有几种情况,第一是数组长度为负数,第二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。还有一种情况是当你调用一个不会终止的递归函数时。
常见错误信息如:Uncaught RangeError: Maximum Call Stack;Uncaught RangeError: Invalid array length;
4. TypeError类型错误
变量或参数不是预期类型时发生的错误。比如使用new字符串、布尔值等原始类型和调用对象不存在的方法就会抛出这种错误,因为new命令的参数应该是一个构造函数。
常见错误类型如:Uncaught TypeError: Cannot Read Property;TypeError: ‘undefined’ Is Not an Object (evaluating…);TypeError: Null Is Not an Object (evaluating…);TypeError: ‘undefined’ Is Not a Function;TypeError: Cannot Read Property ‘length’;Uncaught TypeError: Cannot Set Property;
5. URIError,URL错误
主要是相关函数的参数不正确。
创建错误信息如:Uncaught URIError: URI malformed at decodeURI;
总结&解决方案:运行时错误是js代码中最常见的,原则上说它是js代码中最严重的错误,因为它会阻断js代码的运行,如果你不去捕获并处理它,接下来的js代码都不会再执行了。它也是比较容易定位和解决的一种js错误,因为它有非常详细的错误堆栈,可以精确到行列号。借此,我们就可以定位到js错误发生的具体位置。通过sourceMap映射文件,我们也可直接定位到它的源码位置。也可以跳转到行为轨迹上,分析它发生环境和时机。如图:
面对复杂的业务需求,有时候我们不得不定义一些错误,来帮助我们排查问题。
第一种,比如接口返回了异常结果,但是接口本身是一个正常的请求,这个时候我们就需要把接口返回的状态码以错误的形式进行统计,但是这类错误跟运行时代码错误有着本质的区别,所以并不能以错误的形式进行上报,我们可以将其列为自定义错误。
第二种,由我们引入的第三方库发出的报错。第三方为了保证业务的运行,一般不会抛出错误(throw error),因为throw error一定会阻断业务逻辑,所以他们一般都会采用:先捕获异常,然后采用 console.error的形式打印出报错信息或者警告信息,例如,jquery、vue.js、react.js等框架都会出现一些常见的警告信息。
第三种,由我们自己定义error,通常是打印一句error message,如:console.error(\”我报错了\”)
总结:所有通过console.error打印出来的错误,我们都将其定义为【自定义错误】。因为利用console.error打印message的方式,必然是我们已经知道了处理方式,即使第三方库也是如此。自定义错误没有错误堆栈,无法定位到具体的代码位置,但是它可以补全我们排查的链路。如图:
当未捕获的 JavaScript 错误违背跨域原则时,就会发生脚本错误。例如,如果将 JavaScript 代码托管在 CDN 上,则任何未被捕获的错误(通过 window.onerror 处理程序发出的错误,而不是 try-catch 中捕获到的错误)将仅报告为“脚本错误”。这是浏览器的一种安全机制,主要用于防止跨域传递数据的情况出现。
通常我们可以不用关注或者解决这种错误,因为是第三方的错误,所以我们自己无法解决。 如果到了不得不解决的时候,我们可以提供详细的行为记录和发生的时机,然后让第三方来解决。
还有一种方式,将第三方的js文件的跨域头Access-Control-Allow-Origin 设置为 *, 表示可以从任何域正确访问资源(需要第三方同意)。或者感觉将第三方文件直接放到自己的域名下,这样就可以定位到错误了。
1. 未处理的异常:unhandledrejection
当我们使用Promise的时候,被reject且没有reject处理器的时候,会触发 unhandledrejection 事件;这个时候,就会报一个错误:unhanled rejection;没有堆栈信息,只能依靠行为轨迹来定位错误发生的时机。
2. 内存泄漏
js的内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。通俗点就是指由于疏忽或者错误造成程序未能释放已经不再使用的内存,不再用到的内存却没有及时释放,从而造成内存上的浪费。
如何避免:在局部作用域中,等函数执行完毕,变量就没有存在的必要了,垃圾回收机制很亏地做出判断并且回收,但是对于全局变量,很难判断什么时候不用这些变量,无法正常回收;所以,尽量少使用全局变量。在使用闭包的时候,就会造成严重的内存泄漏,因为闭包中的局部变量,会一直保存在内存中。
我们在书写逻辑的时候,比如作为第三方库的时候,对于严重的错误,我们无法进行处理,可以直接将错误抛出来,警告使用者。但是throw error会阻断程序运行,请谨慎使用。
throw new Error(\”出错了!\”); throw new RangeError(\”出错了,变量超出有效范围!\”); throw new TypeError(\”出错了,变量类型无效!\”);
好了,以上就是我总结常见错误问题,我也会持续补充。
JavaScript 常见错误与异常处理
了解常见的JavaScript错误可以帮助你更好地调试和故障排除代码。当你遇到错误时,能够快速识别错误类型并找到解决方法,可以节省大量的时间和精力。
通过了解常见的JavaScript错误,你可以编写更健壮和稳定的代码。你可以预先考虑到可能出现的错误情况,并采取适当的措施来处理或避免这些错误,从而提高代码的质量和稳定性。
JavaScript错误可能会导致应用程序崩溃、功能失效或不可预料的行为。通过了解常见的JavaScript错误并处理它们,可以提供更好的用户体验,避免应用程序因错误而中断或表现不正常。
某些JavaScript错误可能会暴露应用程序的漏洞,使其易受攻击。了解这些错误并采取适当的安全措施可以帮助你保护应用程序免受潜在的安全威胁。
通过了解常见的JavaScript错误,你可以不断学习和成长。你可以深入了解错误的原因、背后的概念和解决方法,从而提高自己的技能和知识水平。
JS报错会导致程序的执行中断,代码无法继续执行下去。
报错可能导致程序的功能异常或不可用。例如,如果某个关键函数报错,可能会导致相关功能无法正常运行。
严重的JS报错可能导致整个页面崩溃,无法正常显示或交互。
报错信息可能会被显示在页面上,这可能会泄露敏感信息,给攻击者提供潜在的安全漏洞。
JS报错可能会导致页面加载缓慢或卡顿,影响用户的体验。
某些报错可能会导致数据丢失或损坏,特别是在涉及到数据处理或存储的情况下。
不同浏览器对JS的处理方式可能不同,报错可能会导致兼容性问题,使得页面在某些浏览器上无法正常工作。
因此,及时处理和修复JS报错是非常重要的,以确保程序的正常运行和用户体验。
解决方法:确保你对值的操作和使用是符合其类型的。
解决方法:确保你在使用变量或函数之前进行了正确的声明和定义。
解决方法:仔细检查代码,确保语法正确,例如括号匹配、分号使用等。
解决方法:确保你在访问数组、字符串或其他可迭代对象时,使用的索引或位置在有效范围内。
function recursiveFunction(depth) {
if (depth === 0) {
return;
}
recursiveFunction(depth – 1);
}
recursiveFunction(100);
// 在这个示例中,我们通过增加一个停止条件来修复范围错误。递归的深度被限制在100次。
在JavaScript中,EvalError是一个错误类型,表示与eval()函数相关的错误。然而,在现代的JavaScript环境中,EvalError的使用相对较少。 示例:
解决方法:避免使用 eval 函数,尽量使用其他更安全的替代方法。例如使用Function构造函数或解析器工具等。
解决方法:确保你在使用 URI 相关函数或方法时,提供的参数是合法的。
解决方法:InternalError通常是由于JavaScript引擎或运行时环境中的内部问题导致的,例如堆栈溢出、内存不足等。避免出现无限递归、死循环等问题,确保你的代码逻辑正确。
解决方法:使用适当的错误处理机制,例如使用 try-catch 或 catch 方法来捕获和处理异步错误。
async function fetchData() {
try {
throw new Error(\’Something went wrong\’); // 抛出一个错误
} catch (error) {
console.log(\’Sync error:\’, error); // 捕获同步错误并进行处理 }}
fetchData()
.catch(error => {
console.log(\’Async error:\’, error); // 捕获异步错误并进行处理
});
1. 错误处理和异常处理是前端开发中不可或缺的一部分,能够提升用户体验,减少用户流失率:
综合上述几种异常错误,在部门小程序项目中进行了JS报错异常优化,第一版本优化后错误数上线后由每日最高1374次降低到184次,减少了近86%的错误次数,由错误人数 694降低到109人,减少了近84%错误人数。
2.了解常见错误类型和异常类型,以及相应的解决方法,可以帮助我们更好地定位和解决问题。
3. 示例提供了一些常见错误的解决方法,但实际情况可能因代码和环境而异,需要仔细分析和调试代码。
4. 参考文章提供了更多学习资源和深入了解错误处理的内容。
•MDN Web 文档:https://developer.mozilla.org/
•JavaScript 教程 – W3Schools:https://www.w3schools.com/js/
•JavaScript 错误处理和调试 – JavaScript.info:https://javascript.info/try-catch
•JavaScript 异常处理的艺术 – Smashing Magazine:https://www.smashingmagazine.com/2020/08/error-handling-art-javascript/
•JavaScript 异常处理的 8 个技巧 – SitePoint:https://blog.logrocket.com/5-common-javascript-exception-handling-mistakes/
作者:京东零售 孙鹏红
来源:京东云开发者社区 本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。