如何捕获Next.js中window.URL.createObjectURL执行失败的错误?
解决createObjectURL错误无法被捕获的问题
你当前的try/catch抓不到错误,核心原因是错误发生在XMLHttpRequest的异步回调(onloadend)里——外层try块只覆盖了同步执行的代码(比如初始化XHR、调用send),异步回调触发时,外层的catch逻辑已经执行完毕,根本管不到回调内部的错误。
直接调整代码结构就能解决,同时还要兼顾XHR请求本身的错误处理:
修改后的代码
function saveOrOpenBlob(url, blobName, changeName) { if (timer) { clearTimeout(timer); } let blob; let xmlHTTP = new XMLHttpRequest(); xmlHTTP.open("GET", url, true); xmlHTTP.responseType = "arraybuffer"; xmlHTTP.onload = function (e) { blob = new Blob([this.response]); }; xmlHTTP.onprogress = function (pr) { setDownloadProgress((pr.loaded / pr.total) * 100); }; // 处理XHR请求阶段的错误(比如网络失败、资源404/500) xmlHTTP.onerror = function() { setDownloading(false); setDownloadProgress(0); setAlert("下载请求失败,请检查链接是否有效", "error", 4000); }; xmlHTTP.onloadend = function (e) { try { // 提前检查blob有效性,避免空对象传入createObjectURL if (!blob || blob.size === 0) { throw new Error("获取到的文件内容无效"); } let fileName = blobName; let tempEl = document.createElement("a"); document.body.appendChild(tempEl); tempEl.style = "display: none"; url = window.URL.createObjectURL(blob); tempEl.href = url; if (changeName) { tempEl.download = fileName; } tempEl.click(); window.URL.revokeObjectURL(url); timer = setTimeout(() => { setDownloading(false); setDownloadProgress(0); }, 1000); } catch (error) { setDownloading(false); setDownloadProgress(0); setAlert(`下载出错:${error.message}`, "error", 4000); } }; xmlHTTP.send(); }
关键改动说明
- 将try/catch直接包裹在
onloadend内部的代码块中,确保回调里的错误能被捕获 - 新增
xmlHTTP.onerror事件监听,处理请求阶段的网络或HTTP错误 - 在try块开头检查blob的有效性,提前抛出错误,避免走到createObjectURL才触发异常
内容的提问来源于stack exchange,提问作者Perry
相关产品推荐
相关产品推荐

