Skip to content
6 changes: 4 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,14 @@ export function createOptionalCallbackFunction<T, A extends unknown[]>(
return ((...args: A | [...A, ErrorFirstCallback<T>]) => {
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));
}
Expand Down
43 changes: 43 additions & 0 deletions test/types-tests.spec.ts
Original file line number Diff line number Diff line change
@@ -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 = `<x xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' Id='_1'></x>`;

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<SignedXml> = (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("");
});
});