Skip to content

Commit

Permalink
lib,crypto: add optional cause to DOMException
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Aug 12, 2022
1 parent 159b4d7 commit ed6e2a7
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 28 deletions.
7 changes: 3 additions & 4 deletions lib/internal/crypto/aes.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,10 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) {
}

const key = await generateKey('aes', { length }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason' +
`[${err.message}]`,
'OperationError');
'The operation failed for an operation-specific reason',
'OperationError',
err);
});

return new InternalCryptoKey(
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/cfrg.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ async function cfrgGenerateKey(algorithm, extractable, keyUsages) {
}

const keyPair = await generateKeyPair(genKeyType).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
'OperationError',
err);
});

let publicUsages;
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/ec.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) {
}

const keypair = await generateKeyPair('ec', { namedCurve }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
'OperationError',
err);
});

let publicUsages;
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/mac.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
}

const key = await generateKey('hmac', { length }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
'OperationError',
err);
});

return new InternalCryptoKey(
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ async function rsaKeyGenerate(
modulusLength,
publicExponent: publicExponentConverted,
}).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
'OperationError',
err);
});

const keyAlgorithm = {
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,10 @@ const validateByteSource = hideStackFrames((val, name) => {

function onDone(resolve, reject, err, result) {
if (err) {
// TODO(@panva): add err as cause to DOMException
return reject(lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError'));
'OperationError',
err));
}
resolve(result);
}
Expand Down
14 changes: 12 additions & 2 deletions lib/internal/per_context/domexception.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,23 @@ const disusedNamesSet = new SafeSet()
.add('ValidationError');

class DOMException {
constructor(message = '', name = 'Error') {
constructor(message = '', name = 'Error', cause = undefined) {
ErrorCaptureStackTrace(this);
internalsMap.set(this, {
message: `${message}`,
name: `${name}`
name: `${name}`,
cause
});
}

get cause() {
const internals = internalsMap.get(this);
if (internals === undefined) {
throwInvalidThisError(TypeError, 'DOMException');
}
return internals.cause;
}

get name() {
const internals = internalsMap.get(this);
if (internals === undefined) {
Expand Down Expand Up @@ -93,6 +102,7 @@ ObjectDefineProperties(DOMException.prototype, {
[SymbolToStringTag]: { __proto__: null, configurable: true, value: 'DOMException' },
name: { __proto__: null, enumerable: true, configurable: true },
message: { __proto__: null, enumerable: true, configurable: true },
cause: { __proto__: null, enumerable: true, configurable: true },
code: { __proto__: null, enumerable: true, configurable: true }
});

Expand Down
4 changes: 2 additions & 2 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,9 +498,9 @@ const lazyDOMExceptionClass = () => {
return _DOMException;
};

const lazyDOMException = hideStackFrames((message, name) => {
const lazyDOMException = hideStackFrames((message, name, cause) => {
_DOMException ??= internalBinding('messaging').DOMException;
return new _DOMException(message, name);
return new _DOMException(message, name, cause);
});

const kEnumerableProperty = ObjectCreate(null);
Expand Down
21 changes: 15 additions & 6 deletions test/parallel/test-webcrypto-encrypt-decrypt-aes.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
});

decryptionFailing.forEach((vector) => {
variations.push(assert.rejects(testDecrypt(vector), {
name: 'OperationError'
variations.push(assert.rejects(testDecrypt(vector), (err) => {
assert.strictEqual(err.name, 'OperationError');
assert.ok(err.cause instanceof Error);
assert.match(err.cause?.message, /bad decrypt/);
return true;
}));
});

Expand Down Expand Up @@ -157,8 +160,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
});

decryptionFailing.forEach((vector) => {
variations.push(assert.rejects(testDecrypt(vector), {
name: 'OperationError'
variations.push(assert.rejects(testDecrypt(vector), (err) => {
assert.strictEqual(err.name, 'OperationError');
assert.ok(err.cause instanceof Error);
assert.match(err.cause?.message, /foo/);
return true;
}));
});

Expand Down Expand Up @@ -194,8 +200,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
});

decryptionFailing.forEach((vector) => {
variations.push(assert.rejects(testDecrypt(vector), {
name: 'OperationError'
variations.push(assert.rejects(testDecrypt(vector), (err) => {
assert.strictEqual(err.name, 'OperationError');
assert.ok(err.cause instanceof Error);
assert.match(err.cause?.message, /foo/);
return true;
}));
});

Expand Down
7 changes: 5 additions & 2 deletions test/parallel/test-webcrypto-encrypt-decrypt-rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,11 @@ async function testEncryptionLongPlaintext({ algorithm,
newplaintext[plaintext.byteLength] = 32;

return assert.rejects(
subtle.encrypt(algorithm, publicKey, newplaintext), {
name: 'OperationError'
subtle.encrypt(algorithm, publicKey, newplaintext), (err) => {
assert.strictEqual(err.name, 'OperationError');
assert.ok(err.cause instanceof Error);
assert.match(err.cause?.message, /data too large for key size/);
return true;
});
}

Expand Down
7 changes: 5 additions & 2 deletions test/parallel/test-webcrypto-keygen.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,11 @@ const vectors = {
modulusLength,
publicExponent: new Uint8Array(publicExponent),
hash
}, true, usages), {
name: 'OperationError',
}, true, usages), (err) => {
assert.strictEqual(err.name, 'OperationError');
assert.ok(err.cause instanceof Error);
assert.match(err.cause?.message, /pub exponent out of range/);
return true;
});
}));
}
Expand Down

0 comments on commit ed6e2a7

Please sign in to comment.