From c97046e21fd5a5f373048f825626a768997440c2 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Tue, 29 Aug 2023 15:12:37 -0400 Subject: [PATCH] chore(marshal): Consistently assert behavior of makeEncodePassable remotable/promise/error callbacks --- packages/marshal/src/encodePassable.js | 38 +++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/marshal/src/encodePassable.js b/packages/marshal/src/encodePassable.js index c24dc48be9..df60d6ce84 100644 --- a/packages/marshal/src/encodePassable.js +++ b/packages/marshal/src/encodePassable.js @@ -433,6 +433,21 @@ const decodeTagged = (encoded, decodeArray, decodePassable) => { return makeTagged(tag, payload); }; +const assertEncodedRemotable = encoding => { + encoding.startsWith('r') || + Fail`internal: Remotable encoding must start with "r": ${encoding}`; +}; + +const assertEncodedPromise = encoding => { + encoding.startsWith('?') || + Fail`internal: Promise encoding must start with "?": ${encoding}`; +}; + +const assertEncodedError = encoding => { + encoding.startsWith('!') || + Fail`internal: Error encoding must start with "!": ${encoding}`; +}; + /** * @typedef {object} EncodeOptions * @property {( @@ -469,7 +484,19 @@ export const makeEncodePassable = (encodeOptions = {}) => { const innerEncode = passable => { if (isErrorLike(passable)) { - return encodeError(passable, innerEncode); + // We pull out this special case to accommodate errors that are not + // valid Passables. For example, because they're not frozen. + // The special case can only ever apply at the root, and therefore + // outside the recursion, since an error could only be deeper in + // a passable structure if it were passable. + // + // We pull out this special case because, for these errors, we're much + // more interested in reporting whatever diagnostic information they + // carry than we are about reporting problems encountered in reporting + // this information. + const result = encodeError(passable, innerEncode); + assertEncodedError(result); + return result; } const passStyle = passStyleOf(passable); switch (passStyle) { @@ -493,20 +520,17 @@ export const makeEncodePassable = (encodeOptions = {}) => { } case 'remotable': { const result = encodeRemotable(passable, innerEncode); - result.startsWith('r') || - Fail`internal: Remotable encoding must start with "r": ${result}`; + assertEncodedRemotable(result); return result; } case 'error': { const result = encodeError(passable, innerEncode); - result.startsWith('!') || - Fail`internal: Error encoding must start with "!": ${result}`; + assertEncodedError(result); return result; } case 'promise': { const result = encodePromise(passable, innerEncode); - result.startsWith('?') || - Fail`internal: Promise encoding must start with "?": ${result}`; + assertEncodedPromise(result); return result; } case 'symbol': {