当前位置: 首页 > Web前端 > vue.js

try..catch抓不到的错误是什么?有什么注意事项?

时间:2023-03-31 15:15:28 vue.js

作者:AshishLahoti译者:前端小智来源:codingnconcept有梦想,有干货,微信搜索【大千世界】关注这位凌晨还在洗碗的洗碗智慧。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。在今天的内容中,让我们学习使用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);}Errorcaughtbyouterblock:??errorwhileexecutingthecode1.3try..finally不推荐只使用try..finally而没有catch块,看下面发生了什么:try{扔newError('Errorwhileexecutingthecode');}finally{console.log('finally');}finally??UncaughtError:Errorwhileexecutingthecode这里注意两件事:即使在从try块中抛出错误之后,也会执行finally块如果没有catch块,错误不会被优雅的处理,导致未捕获的错误1.4try..catch..finally推荐使用一个try...catch块和一个可选的finally块try{console.log("尝试块开始");thrownewError('执行代码时出错');console.log("Endoftryblock--neverreached");}catch(err){console.error(err.message);}finally{console.log('Finallyblockalwaysrun');}console.log("Codeexecutionoutsidetry-catch-finallyblockcontinue..");Startoftryblock??ErrorwhileexecutingthecodeFinallyblockalwaysrunCodeexecutionoutsidetry-catch-finallyblockcontinue..这里还有两点需要注意:try块抛出错误后,即使try块抛出错误也不会执行后续代码。finally块仍然被执行finally块通常用于清理资源或关闭流,像这样:try{openFile(file);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);}CustomErrorTypeErrorCannotreadproperty'name'ofnull我是小智,下次再见!编辑过程中可能存在的BUG无法实时获知。之后为了解决这些bug,花费了大量的时间在日志调试上。顺便给大家推荐一个好用的BUG监控工具Fundebug原文:https://codings.com/javascrip...交流有梦想,有干货,微信搜索【大千世界】关注这个洗碗智慧谁一大早还在洗碗。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。