Skip to content

Commit ed6e2a7

Browse files
committed
lib,crypto: add optional cause to DOMException
1 parent 159b4d7 commit ed6e2a7

File tree

11 files changed

+52
-28
lines changed

11 files changed

+52
-28
lines changed

lib/internal/crypto/aes.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,10 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) {
241241
}
242242

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

251250
return new InternalCryptoKey(

lib/internal/crypto/cfrg.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ async function cfrgGenerateKey(algorithm, extractable, keyUsages) {
150150
}
151151

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

159159
let publicUsages;

lib/internal/crypto/ec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) {
112112
}
113113

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

121121
let publicUsages;

lib/internal/crypto/mac.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
6666
}
6767

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

7575
return new InternalCryptoKey(

lib/internal/crypto/rsa.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ async function rsaKeyGenerate(
178178
modulusLength,
179179
publicExponent: publicExponentConverted,
180180
}).catch((err) => {
181-
// TODO(@panva): add err as cause to DOMException
182181
throw lazyDOMException(
183182
'The operation failed for an operation-specific reason',
184-
'OperationError');
183+
'OperationError',
184+
err);
185185
});
186186

187187
const keyAlgorithm = {

lib/internal/crypto/util.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,10 @@ const validateByteSource = hideStackFrames((val, name) => {
279279

280280
function onDone(resolve, reject, err, result) {
281281
if (err) {
282-
// TODO(@panva): add err as cause to DOMException
283282
return reject(lazyDOMException(
284283
'The operation failed for an operation-specific reason',
285-
'OperationError'));
284+
'OperationError',
285+
err));
286286
}
287287
resolve(result);
288288
}

lib/internal/per_context/domexception.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,23 @@ const disusedNamesSet = new SafeSet()
4949
.add('ValidationError');
5050

5151
class DOMException {
52-
constructor(message = '', name = 'Error') {
52+
constructor(message = '', name = 'Error', cause = undefined) {
5353
ErrorCaptureStackTrace(this);
5454
internalsMap.set(this, {
5555
message: `${message}`,
56-
name: `${name}`
56+
name: `${name}`,
57+
cause
5758
});
5859
}
5960

61+
get cause() {
62+
const internals = internalsMap.get(this);
63+
if (internals === undefined) {
64+
throwInvalidThisError(TypeError, 'DOMException');
65+
}
66+
return internals.cause;
67+
}
68+
6069
get name() {
6170
const internals = internalsMap.get(this);
6271
if (internals === undefined) {
@@ -93,6 +102,7 @@ ObjectDefineProperties(DOMException.prototype, {
93102
[SymbolToStringTag]: { __proto__: null, configurable: true, value: 'DOMException' },
94103
name: { __proto__: null, enumerable: true, configurable: true },
95104
message: { __proto__: null, enumerable: true, configurable: true },
105+
cause: { __proto__: null, enumerable: true, configurable: true },
96106
code: { __proto__: null, enumerable: true, configurable: true }
97107
});
98108

lib/internal/util.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,9 @@ const lazyDOMExceptionClass = () => {
498498
return _DOMException;
499499
};
500500

501-
const lazyDOMException = hideStackFrames((message, name) => {
501+
const lazyDOMException = hideStackFrames((message, name, cause) => {
502502
_DOMException ??= internalBinding('messaging').DOMException;
503-
return new _DOMException(message, name);
503+
return new _DOMException(message, name, cause);
504504
});
505505

506506
const kEnumerableProperty = ObjectCreate(null);

test/parallel/test-webcrypto-encrypt-decrypt-aes.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
118118
});
119119

120120
decryptionFailing.forEach((vector) => {
121-
variations.push(assert.rejects(testDecrypt(vector), {
122-
name: 'OperationError'
121+
variations.push(assert.rejects(testDecrypt(vector), (err) => {
122+
assert.strictEqual(err.name, 'OperationError');
123+
assert.ok(err.cause instanceof Error);
124+
assert.match(err.cause?.message, /bad decrypt/);
125+
return true;
123126
}));
124127
});
125128

@@ -157,8 +160,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
157160
});
158161

159162
decryptionFailing.forEach((vector) => {
160-
variations.push(assert.rejects(testDecrypt(vector), {
161-
name: 'OperationError'
163+
variations.push(assert.rejects(testDecrypt(vector), (err) => {
164+
assert.strictEqual(err.name, 'OperationError');
165+
assert.ok(err.cause instanceof Error);
166+
assert.match(err.cause?.message, /foo/);
167+
return true;
162168
}));
163169
});
164170

@@ -194,8 +200,11 @@ async function testDecrypt({ keyBuffer, algorithm, result }) {
194200
});
195201

196202
decryptionFailing.forEach((vector) => {
197-
variations.push(assert.rejects(testDecrypt(vector), {
198-
name: 'OperationError'
203+
variations.push(assert.rejects(testDecrypt(vector), (err) => {
204+
assert.strictEqual(err.name, 'OperationError');
205+
assert.ok(err.cause instanceof Error);
206+
assert.match(err.cause?.message, /foo/);
207+
return true;
199208
}));
200209
});
201210

test/parallel/test-webcrypto-encrypt-decrypt-rsa.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ async function testEncryptionLongPlaintext({ algorithm,
126126
newplaintext[plaintext.byteLength] = 32;
127127

128128
return assert.rejects(
129-
subtle.encrypt(algorithm, publicKey, newplaintext), {
130-
name: 'OperationError'
129+
subtle.encrypt(algorithm, publicKey, newplaintext), (err) => {
130+
assert.strictEqual(err.name, 'OperationError');
131+
assert.ok(err.cause instanceof Error);
132+
assert.match(err.cause?.message, /data too large for key size/);
133+
return true;
131134
});
132135
}
133136

0 commit comments

Comments
 (0)