diff --git a/src/types.ts b/src/types.ts index 08c4300f..322273fe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -253,12 +253,14 @@ export function createOptionalCallbackFunction( return ((...args: A | [...A, ErrorFirstCallback]) => { const possibleCallback = args[args.length - 1]; if (isErrorFirstCallback(possibleCallback)) { + let result: T; try { - const result = syncVersion(...(args.slice(0, -1) as A)); - possibleCallback(null, result); + result = syncVersion(...(args.slice(0, -1) as A)); } catch (err) { possibleCallback(err instanceof Error ? err : new Error("Unknown error")); + return; } + possibleCallback(null, result); } else { return syncVersion(...(args as A)); } diff --git a/test/types-tests.spec.ts b/test/types-tests.spec.ts new file mode 100644 index 00000000..037b4e47 --- /dev/null +++ b/test/types-tests.spec.ts @@ -0,0 +1,43 @@ +import { SignedXml, type ErrorFirstCallback } from "../src/index"; +import * as fs from "fs"; +import { expect } from "chai"; + +describe("Callback invocation", function () { + const xml = ``; + + function createSigner(privateKey: Buffer): SignedXml { + const sig = new SignedXml(); + sig.privateKey = privateKey; + sig.addReference({ + xpath: "//*[local-name(.)='x']", + digestAlgorithm: "http://www.w3.org/2000/09/xmldsig#sha1", + transforms: ["http://www.w3.org/2001/10/xml-exc-c14n#"], + }); + sig.canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#"; + sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; + return sig; + } + + it("invokes the callback once when the callback throws", function () { + const sig = createSigner(fs.readFileSync("./test/static/client.pem")); + + const errorsSeen: (string | null)[] = []; + const callback: ErrorFirstCallback = (err) => { + errorsSeen.push(err ? err.message : null); + throw new Error("Error Thrown"); + }; + + expect(() => sig.computeSignature(xml, callback)).to.throw("Error Thrown"); + expect(errorsSeen).to.deep.equal([null]); + }); + + it("invokes the callback once, with an error, when signing fails", function () { + const sig = createSigner(fs.readFileSync("./test/static/client_public.pem")); + + const outcomes: string[] = []; + sig.computeSignature(xml, (err) => outcomes.push(err ? "error" : "success")); + + expect(outcomes).to.deep.equal(["error"]); + expect(sig.getSignedXml()).to.equal(""); + }); +});