node.js - azure blob storage nodejs v10 - 应用程序抛出未捕获的异常并终止
问题描述
环境:
- nodejs 10.15.2,表达 4.16.4
- 发生在 azure 应用服务以及本地测试环境中
- 使用“@azure/storage-blob”:“^10.3.0”
我正在创建一个快速应用程序来向/从 azure blob 存储上传/下载 blob。一切正常:可以上传 blob、设置元数据、下载 blob 等。但是:当 aborter(s) 遇到超时时,它们会导致终止节点进程的 ancaught excpetion。
错误堆栈是:
Fri Apr 19 2019 07:38:28 GMT+0000 (Greenwich Mean Time): Application has thrown an uncaught exception and is terminated:
Error: The request was aborted
at new RestError (D:\home\site\wwwroot\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1397:28)
at a.<anonymous> (D:\home\site\wwwroot\node_modules\mql\node_modules\@azure\storage-blob\dist\index.js:1:11269)
at D:\home\site\wwwroot\node_modules\mql\node_modules\@azure\storage-blob\dist\index.js:1:1277
at Array.forEach (<anonymous>)
at a.abort (D:\home\site\wwwroot\node_modules\mql\node_modules\@azure\storage-blob\dist\index.js:1:1255)
at Timeout.<anonymous> (D:\home\site\wwwroot\node_modules\mql\node_modules\@azure\storage-blob\dist\index.js:1:519)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at unrefdHandle (timers.js:520:7)
at Timer.processTimers (timers.js:222:12)
在我的本地开发环境中,我在未捕获的异常上放置了一个断点,并发现:
事件最终在 event.js 中抛出(发射)
它是由 RetriableReadableStream 引起的,(@azure/storage-blob/dist/esm/lib/utils/RetriableReadableStream),请参阅“aborter.addEventListener”:
function RetriableReadableStream(aborter, source, getter, offset, count, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this) || this;
_this.retries = 0;
_this.aborter = aborter;
_this.getter = getter;
_this.source = source;
_this.start = offset;
_this.offset = offset;
_this.end = offset + count - 1;
_this.maxRetryRequests =
options.maxRetryRequests && options.maxRetryRequests >= 0
? options.maxRetryRequests
: 0;
_this.progress = options.progress;
_this.options = options;
aborter.addEventListener("abort", function () {
_this.source.pause();
_this.emit("error", new RestError("The request was aborted", RestError.REQUEST_ABORTED_ERROR));
});
...
- 这又是由流产者引起的:
Aborter.prototype.abort = function () {
var _this = this;
if (this.aborted) {
return;
}
this.cancelTimer();
if (this.onabort) {
this.onabort.call(this);
}
this.abortEventListeners.forEach(function (listener) {
listener.call(_this);
});
this.children.forEach(function (child) { return child.cancelByParent(); });
this._aborted = true;
};
我的 Aborter 是这样创建的:
createAborter(): Aborter {
let aborter = Aborter.timeout(5 * ONE_MINUTE);
aborter.onabort = () => {
console.warn(`AzureBlog.createAborter.onAbort: Request was aborted.`);
}
return aborter;
}
...我的下载看起来像这样:
async download(blobName: string): Promise<NodeJS.ReadableStream> {
const blockBlobURL = this.getBlockBlobUrl(blobName);
const downloadResponse = await blockBlobURL.download(this.createAborter(), 0);
if (!downloadResponse) {
throw new Error(`Download returned undefined.`);
}
if (!downloadResponse.readableStreamBody) {
throw new Error(`downloadResponse.readableStreamBody is undefined.`);
}
return downloadResponse.readableStreamBody;
}
...我像这样将它流式传输到客户端:
self.expressApp.route('/download')
.get(jsonParser, async (req: Request, resp: Response) => {
handleDownload(req, resp);
}).post(jsonParser, async (req: Request, resp: Response) => {
handleDownload(req, resp);
});
...
let blobReadStream = await self.azureBlobStore.download(id);
blobReadStream.pipe(resp);
如前所述,一切正常,直到超时。我不明白的是:
- 为什么有人会在基础库中抛出未捕获的错误而不允许库使用者捕获它?(顺便说一句,与 azure gremlin nodejs 有同样的问题)
- 我的中止程序“onAbort()”只是添加了另一个事件监听器。我是否必须删除所有其他侦听器以防止该错误?
- 为什么“中止”的听众会被解雇?所有请求(下载、上游等)都可以在几秒钟内正常工作。样本/文档没有说明在成功请求后手动销毁/禁用中止程序。
我假设我误解了 Aborter-conecpt。因此,非常感谢任何帮助。
非常感谢!
解决方案
推荐阅读
- c++ - 每个条件唤醒多个线程工作一次
- laravel - 一起使用 Laravel Sanctum SPA auth 和 Auth UI
- c# - 两个控件相互更新时如何防止stackoverflow异常
- c# - void 方法的 C# 8 开关表达式
- python - 如何在python的for循环中增加一个变量
- python - 字符串分析:按单词百分比将字符串分成 n 部分
- tensorflow - 与 tensorflow.keras 相比,在 mnist 上使用 keras 的测试准确度显着提高
- python - matplotlib 颜色图中的对数颜色条
- wicket - 如何禁用检票口中的 AjaxLink 按钮?
- python - 我正在尝试让用户回复机器人响应,然后发送另一条消息