作者:AshishLahoti译者:前端小智来源:codingnconcept再次点赞,微信搜索【大千世界】,B站关注【前端小智】这个没有大厂背景,但是有一个积极的态度的人。本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。**近期开源了一个Vue组件,但还不够完善,欢迎大家一起完善,希望大家给个star支持一下,谢谢大家。github地址:https://github.com/qq44924588...今天的内容,我们来学习一下如何使用try、catch、finally和throw进行错误处理。我们还将讨论JS中的内置错误对象(Error、SyntaxError、ReferenceError等)以及如何定义自定义错误。1、使用try..catch..finally..throw处理JS中的错误,我们主要使用try、catch、finally和throw关键字。try块包含我们需要检查的代码。关键字throw用于抛出自定义错误。catch块处理捕获的错误。finally块是无论最终结果如何都会执行的块。你可以在这个块中做一些需要做的事情。1.1try每个try块必须关联至少一个catch或finally块,否则会抛出SyntaxError错误。我们单独使用try块来验证:try{thrownewError('Errorwhileexecutingthecode');}?UncaughtSyntaxError:Missingcatchorfinallyaftertry1.2try..catch建议配合try使用catch块,它可以优雅地处理try块抛出的错误。try{thrownewError('Errorwhileexecutingthecode');}catch(err){console.error(err.message);}??errorwhileexecutingthecode1.2.1try..catchwithinvalidcodetry..catch无法捕获无效的JS代码,例如try块中的以下代码在语法上是错误的,但不会被catch块捕获。try{~!$%^&*}catch(err){console.log("Thiswillnotbeexecuted");}??UncaughtSyntaxError:Invalidorunexpectedtoken1.2.2try..catch同异步代码,try..catch无法捕获在异步代码中引发的异常,例如setTimeout:");}UncaughtReferenceError将在1秒后抛出:??UncaughtReferenceError:noSuchVariableisnotdefined所以,我们应该在异步代码中使用try..catch来处理错误:setTimeout(function(){try{noSuchVariable;}catch(err){console.log("erroriscaughthere!");}},1000);1.2.3嵌套的try..catch我们也可以使用嵌套的try和catch块来抛出Error,像这样:}catch(err){抛出错误;}}catch(err){console.log("错误被外部块捕捉到:");console.error(err.message);}Errorcatchedbyouterblock:??errorwhileexecutingthecode1.3try..finally不建议只使用try..finally而没有catch块,见下文发生了什么:try{thrownewError('执行co时出错de');}finally{console.log('finally');}finally??UncaughtError:Errorwhileexecutingthecode这里注意两点:finally块即使在try块抛出错误后也会执行,如果有是没有catch块,错误不会被优雅地处理,导致未被捕获的错误1.4try..catch..finally推荐使用try...catch块和可选的finally块thrownewError('执行代码时出错');console.log("Endoftryblock--neverreached");}catch(err){console.error(err.message);}finally{console.log('Finallyblockalwaysrun');}console.log("Codeexecutionoutsidetry-catch-finallyblockcontinue..");Startoftryblock??errorwhileexecutingthecodeFinallyblockalwaysrun代码在try-catch-finallyblockcontinue之外执行..这里还有两点需要注意:try块抛出错误后,后面的代码不会执行即使try块抛出错误后,finally块仍然执行finally块通常用于清理资源或关闭流,如下:try{打开文件(文件);readFile(file);}catch(err){console.error(err.message);}finally{closeFile(file);}1.5throwthrow语句用于抛出异常。throw//throw原语和函数throw"Error404";throw42;throwtrue;throw{toString:function(){return"I'manobject!";}};//throwerrorobjectthrownewError('执行代码时出错');thrownewSyntaxError('语法有问题');thrownewReferenceError('Oops..Wrongreference');//throw自定义错误对象函数ValidationError(message){this.message=message;this.name='ValidationError';}thrownewValidationError('Valuetoohigh');2、异步代码中的错误处理Promise和asyncawait可以用于异步代码中的错误处理。2.1then..catchinPromise我们可以使用then()和catch()将多个Promise链起来处理链中单个Promise的错误,如下:Promise.resolve(1).then(res=>{console.log(res);//print'1'thrownewError('somethingwentwrong');//throwerrorreturnPromise.resolve(2);//这不会被执行}).then(res=>{//这也不会执行,因为错误还没有被处理console.log(res);}).catch(err=>{console.error(err.message);//打印'somethingwentwrong'returnPromise.resolve(3);}).then(res=>{console.log(res);//print'3'}).catch(err=>{//这不会被执行console.error(err);})让我们看一个更现实的例子,我们使用fetch调用返回承诺的API,我们使用catch块来优雅地处理API失败。functionhandleErrors(response){if(!response.ok){throwError(response.statusText);}返回响应;}fetch("http://httpstat.us/500").then(handleErrors).then(response=>console.log("ok")).catch(error=>console.log("Caught",error));CaughtError:InternalServerErrorathandleErrors(:3:15)2.2try..catch和asyncawait在asyncawait中使用try..catch更容易:(asyncfunction(){try{awaitfetch("http://httpstat.us/500");}catch(err){console.error(err.message);}})();让我们看一下同一个示例,我们使用fetch调用返回promise对象的API,并使用try..catch块来优雅地处理API失败。functionhandleErrors(response){if(!response.ok){throwError(response.statusText);}}(asyncfunction(){try{letresponse=awaitfetch("http://httpstat.us/500");handleErrors(response);letdata=awaitresponse.json();返回数据;}catch(error){console.log("Caught",error)}})();在handleErrors(:3:15)在:11:73捕获到错误:内部服务器错误。JS3.1中的内置错误ErrorJavaScript有一个内置的错误对象,通常由try块抛出并在catch块中捕获。Error对象包含以下属性:name:是错误的名称,例如“Error”、“SyntaxError”、“ReferenceError”等。message:包含错误详细信息的消息。堆栈:是用于调试目的的错误堆栈跟踪。我们创建一个Error对象并查看其名称和消息属性:consterr=newError('Errorwhileexecutingthecode');console.log("name:",err.name);console.log("message:",err.message);console.log("stack:",err.stack);name:Errormessage:Errorwhileexecutingthecodestack:Error:Errorwhileexecutingthecodeat:1:13JavaScript构建了以下内容-inErrors,这些错误都继承自Error对象3.2EvalErrorEvalError表示一个关于全局eval()函数的错误,JS不再抛出这个异常,它的存在是为了向后兼容。3.3RangeError当值超出范围时,将引发RangeError。?[].length=-1?UncaughtRangeError:Invalidarraylength3.4ReferenceError当引用一个不存在的变量时会引发ReferenceError。?x=x+1;?UncaughtReferenceError:xisnotdefined3.5SyntaxError当你在JS代码中使用任何错误的语法时,都会引发SyntaxError。?函数(){返回“嗨!”}?未捕获的语法错误:函数语句需要一个函数名?1=1?未捕获的语法错误:分配中的左侧无效?JSON.parse("{x}");?未捕获的语法错误:JSON中位置23.6处的意外标记xTypeError如果值不是预期的类型,则抛出TypeError。?1();?未捕获类型错误:1不是函数?null.name;?未捕获类型错误:无法读取null的属性“名称”3.7URIError如果以错误的方式使用全局URI方法,则会抛出URIError。?decodeURI("%%%");?未捕获的URIError:URI格式错误4。定义并抛出自定义错误我们也可以通过这种方式定义自定义错误。classCustomErrorextendsError{constructor(message){super(message);this.name="自定义错误";}};consterr=newCustomError('执行代码时的自定义错误');console.log("name:",err.name);console.log("message:",err.message);name:CustomErrormessage:Customerrorwhileexecutingthecode我们还可以进一步增强CustomError对象以包含错误代码classCustomErrorextendsError{constructor(message,code){super(message);this.name="自定义错误";这个。代码=代码;}};consterr=newCustomError('执行代码时出现自定义错误',"ERROR_CODE");console.log("name:",err.name);console.log("message:",err.message);console.log("code:",err.code);name:CustomErrormessage:Customerrorwhileexecutingthecodecode:ERROR_CODE在try..catch块中使用它:try{try{null.name;}catch(err){thrownewCustomError(err.message,err.name);//消息,代码}}catch(err){console.log(err.name,err.code,err.message);}CustomErrorTypeError无法读取property'name'ofnull我是小智,下次见!代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://codings.com/javascrip...每周更新交流文章。可以微信搜索“大千世界”阅读即时更新(比博文早一两篇)。这篇文章在GitHubhttps://github.com/qq449245884/小智已经收集整理了很多我的文档。欢迎star和改进。可以参考考点面试复习。另外,关注公众号,后台会回复福利,可以看到福利,你懂的。