在UI过程中,我希望捕获自定义错误,并在Webworker中添加comlink。
自定义错误是扩展错误,因此将序列化/反序列化组合成错误而不是自定义错误。
串行化
if (value instanceof Error) {
serialized = {
isError: true,
value: {
message: value.message,
name: value.name,
stack: value.stack,
},
};
}
反序列化
if (serialized.isError) {
throw Object.assign(
new Error(serialized.value.message),
serialized.value
);
}
我试图自定义throwTransferHandler以引发自定义错误,但它没有工作。因为throwMarker是唯一的符号,不导出。
canHandle: (value): value is ThrownValue =>
isObject(value) && throwMarker in value,
发布于 2022-06-20 13:37:56
最后,我定义了本地模块,该模块重新导出comlink并使用序列化错误作为自定义错误序列化/反序列化。
import * as Comlink from "comlink";
import ErrorCodec from "serialize-error";
export * from "comlink";
interface ThrownValue {
value: unknown;
}
type SerializedThrownValue =
| { isError: true; value: ErrorCodec.ErrorObject }
| { isError: false; value: unknown };
const throwTransferHandler_:
| Comlink.TransferHandler<unknown, unknown>
| undefined = Comlink.transferHandlers.get("throw");
const throwTransferHandler = throwTransferHandler_ as Comlink.TransferHandler<
ThrownValue,
SerializedThrownValue
>;
const throwTransferHandlerCustom: Comlink.TransferHandler<
ThrownValue,
SerializedThrownValue
> = {
canHandle: throwTransferHandler.canHandle,
serialize: ({ value }) => {
let serialized: SerializedThrownValue;
if (value instanceof Error) {
serialized = {
isError: true,
value: ErrorCodec.serializeError(value),
};
} else {
serialized = { isError: false, value };
}
return [serialized, []];
},
deserialize: (serialized) => {
if (serialized.isError) {
const error = ErrorCodec.deserializeError(serialized.value);
throw error;
}
throw serialized.value;
},
};
Comlink.transferHandlers.set("throw", throwTransferHandlerCustom);
应该确保此版本的模块是在所有其他地方导入的,而不是直接的comlink导入。
作为canHandle的另一种选择,您还可以使用getOwnPropertySymbols和toString:
Object.getOwnPropertySymbols({[Symbol("Comlink.thrown")]: 1})
.some(_ => _.toString() === 'Symbol(Comlink.thrown)')
https://stackoverflow.com/questions/65245540
复制相似问题