diff options
author | Florian Dold <florian@dold.me> | 2024-02-15 23:51:35 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-02-15 23:51:35 +0100 |
commit | 490ef893e04d0515c3093a5a3e1cf14e707f3ea6 (patch) | |
tree | be356738aa4ae4d577e24d1c6a6e7b70a2d20501 /packages | |
parent | 42a7a31fb2f10c7d3049d35dec331ed4237cc882 (diff) | |
download | wallet-core-490ef893e04d0515c3093a5a3e1cf14e707f3ea6.tar.gz wallet-core-490ef893e04d0515c3093a5a3e1cf14e707f3ea6.tar.bz2 wallet-core-490ef893e04d0515c3093a5a3e1cf14e707f3ea6.zip |
taler-util: cancellation and timeouts on NodeJS
Diffstat (limited to 'packages')
-rw-r--r-- | packages/taler-util/src/http-impl.node.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/packages/taler-util/src/http-impl.node.ts b/packages/taler-util/src/http-impl.node.ts index 5e613e6cd..ea2309504 100644 --- a/packages/taler-util/src/http-impl.node.ts +++ b/packages/taler-util/src/http-impl.node.ts @@ -184,6 +184,18 @@ export class HttpLibImpl implements HttpRequestLibrary { ); } + let timeoutHandle: NodeJS.Timer | undefined = undefined; + let cancelCancelledHandler: (() => void) | undefined = undefined; + + const doCleanup = () => { + if (timeoutHandle != null) { + clearTimeout(timeoutHandle); + } + if (cancelCancelledHandler) { + cancelCancelledHandler(); + } + }; + return new Promise((resolve, reject) => { const handler = (res: IncomingMessage) => { res.on("data", (d) => { @@ -219,6 +231,7 @@ export class HttpLibImpl implements HttpRequestLibrary { return text; }, }; + doCleanup(); resolve(resp); }); res.on("error", (e) => { @@ -232,6 +245,7 @@ export class HttpLibImpl implements HttpRequestLibrary { }, `Error in HTTP response handler: ${code}`, ); + doCleanup(); reject(err); }); }; @@ -245,6 +259,43 @@ export class HttpLibImpl implements HttpRequestLibrary { throw new Error(`unsupported protocol ${options.protocol}`); } + if (timeoutMs != null) { + timeoutHandle = setTimeout(() => { + logger.info(`request to ${url} timed out`); + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Request timed out after ${timeoutMs} ms`, + ); + timeoutHandle = undefined; + req.destroy(); + doCleanup(); + reject(err); + req.destroy(); + }, timeoutMs); + } + + if (opt?.cancellationToken) { + cancelCancelledHandler = opt.cancellationToken.onCancelled(() => { + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Request cancelled`, + ); + req.destroy(); + doCleanup(); + reject(err); + }); + } + req.on("error", (e: Error) => { const code = "code" in e ? e.code : "unknown"; const err = TalerError.fromDetail( @@ -256,6 +307,7 @@ export class HttpLibImpl implements HttpRequestLibrary { }, `Error in HTTP request: ${code}`, ); + doCleanup(); reject(err); }); |