Ручное исключение ReadableStream или TransformStream приводит к тому, что ошибка регистрируется как неперехваченная ошибка
При вызове https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultController/error илиTransformStreamDefaultController.error
с объектом Error для ручного вывода ошибки из потока, ошибка регистрируется в консоли браузера на сайте вызова как неперехваченная ошибка, как если бы .error()
сам метод повторно выдавал ошибку, в которую он был загружен.
Следующий короткий фрагмент с источником ReadableStream и местом назначения WritableStream демонстрирует проблему, однако кажется, что консоль сниппета stackru не может зарегистрировать ошибку (проверьте консоль браузера в Chrome 80):
let sourceController;
let source = new ReadableStream({
start: (controller) => {
sourceController = controller;
}
});
let destination = new WritableStream({
start: () => {
// ...
},
abort: (reason) => {
console.log("aborted:");
console.log(reason);
}
});
source.pipeTo(destination);
window.setTimeout(() => sourceController.error(new Error("wut?")), 1000);
// ^^^^^
// js:30 Uncaught (in promise) Error: wut?
Судя по сообщению об ошибке, это может быть где-то отклоненное обещание, но я не знаю, где. Как ни странно, попытка наблюдать эту неперехваченную ошибку с помощью следующего слушателя тоже не имеет никакого эффекта:
window.onerror = (e) => console.error(e); // Never gets called
Я бы подумал определить abort
метода назначения WritableStream отмечает, что поток включен с обработкой ошибок, но ошибка по-прежнему регистрируется как неперехваченная ошибка (как ни странно, abort
метод вызывается одновременно).
Мне кажется, что эта ошибка совершенно безобидна, но, безусловно, раздражает.
Как мне от этого избавиться? Добавлениеtry ... catch
вокруг вещь ничего не делает.
1 ответ
Ошибка возникает из-за обещания, возвращенного pipeTo
вызов, потому что ошибка потока приведет к отклонению этого обещания. Решение состоит в том, чтобы добавить недостающее предложение catch:
source.pipeTo(destination).catch(err => ...)
Или в async
контекст исполнения:
try {
await source.pipeTo(destination);
} catch (err) {
...
}
Это объясняется в спецификации WHATWG Streams:
Ошибка в исходном потоке, доступном для чтения, приведет к прерыванию потока назначения, доступного для записи, если preventAbort не является истинным. Возвращенное обещание будет отклонено с ошибкой источника или с любой ошибкой, возникающей во время прерывания назначения.