diff --git a/src/network/utils.ts b/src/network/utils.ts index ddbd48fc0..7b7cb212e 100644 --- a/src/network/utils.ts +++ b/src/network/utils.ts @@ -482,13 +482,37 @@ function fromError(error: any) { return wrappedError.toJSON(); } - // If an error is not serialisable (for example, throwing Object.create(null)) - // then trying to serialise it to a string would throw an error. + // Use the properties of the error to create an appropriate error message. let message = ''; + switch (typeof error) { + case 'boolean': + case 'number': + case 'string': + case 'bigint': + case 'symbol': + message = `Non-error literal ${String(error)} was thrown`; + case 'object': + // Let the fallback handler catch null values. + if (error == null) break; + // If we have an error message defined, then return that. + if ('message' in error && typeof error.message === 'string') { + message = error.message; + } + // If present, mention the constructor name in the message. + if (error.constructor?.name != null) { + message = `Non-error object ${error.constructor.name} was thrown`; + } + // Any other values should be handled by the fallback handler. + break; + } + + // Handle cases where the error is not serialisable, like objects created + // using Object.create(null). Trying to serialise this throws a TypeError. try { - message = `Unexpected error occured: ${error}`; + message = `Non-error value ${String(error)} was thrown`; } catch (e) { - message = 'Unexpected error occured'; + if (e instanceof TypeError) message = 'Non-error value was thrown'; + else throw e; } // If the error was not an Error, then wrap it inside ErrorPolykeyUnexpected