首页 > 解决方案 > azure blob storage nodejs v10 - 应用程序抛出未捕获的异常并终止

问题描述

环境:

我正在创建一个快速应用程序来向/从 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)

在我的本地开发环境中,我在未捕获的异常上放置了一个断点,并发现:

    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);

如前所述,一切正常,直到超时。我不明白的是:

我假设我误解了 Aborter-conecpt。因此,非常感谢任何帮助。

非常感谢!

标签: node.jsazureazure-blob-storage

解决方案


推荐阅读