Repository: karen-irc/option-t
Pull request #1475 (2022-11-20 16:07:27)

Use assertIsErrorInstance() in unwrapOrThrowErrorFromResult() 


Patch:
diff --git a/src/PlainResult/tryCatch.ts b/src/PlainResult/tryCatch.ts
index 1c35cb79..72b071ff 100644
--- a/src/PlainResult/tryCatch.ts
+++ b/src/PlainResult/tryCatch.ts
@@ -1,4 +1,5 @@
-import { assertIsError } from '../internal/assert.js';
+import { assertIsErrorInstance } from '../internal/assert.js';
+import { ERR_MSG_THROWN_VALUE_IS_NOT_BUILTIN_ERROR_INSTANCE } from '../internal/ErrorMessage.js';
 import type { ProducerFn } from '../internal/Function.js';
 import { type Result, createOk, createErr } from './Result.js';
 
@@ -35,7 +36,7 @@ export function tryCatchIntoResultWithEnsureError<T>(producer: ProducerFn<T>): R
         const ok = createOk<T>(value);
         return ok;
     } catch (e: unknown) {
-        assertIsError(e);
+        assertIsErrorInstance(e, ERR_MSG_THROWN_VALUE_IS_NOT_BUILTIN_ERROR_INSTANCE);
         const err = createErr<Error>(e);
         return err;
     }
diff --git a/src/PlainResult/tryCatchAsync.ts b/src/PlainResult/tryCatchAsync.ts
index dc2d969b..477853ac 100644
--- a/src/PlainResult/tryCatchAsync.ts
+++ b/src/PlainResult/tryCatchAsync.ts
@@ -1,5 +1,8 @@
-import { assertIsError, assertIsPromise } from '../internal/assert.js';
-import { ERR_MSG_PRODUCER_MUST_RETURN_PROMISE } from '../internal/ErrorMessage.js';
+import { assertIsErrorInstance, assertIsPromise } from '../internal/assert.js';
+import {
+    ERR_MSG_PRODUCER_MUST_RETURN_PROMISE,
+    ERR_MSG_THROWN_VALUE_IS_NOT_BUILTIN_ERROR_INSTANCE,
+} from '../internal/ErrorMessage.js';
 import type { AsyncProducerFn } from '../internal/Function.js';
 import { mapErrForResult } from './mapErr.js';
 import { type Result, createOk, createErr } from './Result.js';
@@ -51,6 +54,6 @@ function ensureErrorInResultErr<T>(input: Result<T, unknown>): Result<T, Error>
 }
 
 function checkThrownIsError(thrown: unknown): Error {
-    assertIsError(thrown);
+    assertIsErrorInstance(thrown, ERR_MSG_THROWN_VALUE_IS_NOT_BUILTIN_ERROR_INSTANCE);
     return thrown;
 }
diff --git a/src/PlainResult/unwrapOrThrowError.ts b/src/PlainResult/unwrapOrThrowError.ts
index 811e1f0f..76163892 100644
--- a/src/PlainResult/unwrapOrThrowError.ts
+++ b/src/PlainResult/unwrapOrThrowError.ts
@@ -1,3 +1,5 @@
+import { assertIsErrorInstance } from '../internal/assert.js';
+import { ERR_MSG_CONTAINED_TYPE_E_SHOULD_BE_BUILTIN_ERROR_INSTANCE } from '../internal/ErrorMessage.js';
 import { type Result, isOk } from './Result.js';
 import { unwrapErrFromResult, unwrapOkFromResult } from './unwrap.js';
 
@@ -20,14 +22,6 @@ export function unwrapOrThrowErrorFromResult<T>(input: Result<T, Error>): T {
     }
 
     const e: unknown = unwrapErrFromResult(input);
-    if (!(e instanceof Error)) {
-        throw new TypeError(
-            `The contained E should be \`Error\` instance but that was \`${String(e)}\``,
-            {
-                cause: e,
-            }
-        );
-    }
-
+    assertIsErrorInstance(e, ERR_MSG_CONTAINED_TYPE_E_SHOULD_BE_BUILTIN_ERROR_INSTANCE);
     throw e;
 }
diff --git a/src/internal/ErrorMessage.ts b/src/internal/ErrorMessage.ts
index 9bee7413..60d4b72d 100644
--- a/src/internal/ErrorMessage.ts
+++ b/src/internal/ErrorMessage.ts
@@ -20,3 +20,11 @@ export const ERR_MSG_RECOVERER_MUST_RETURN_PROMISE =
 
 export const ERR_MSG_PRODUCER_MUST_RETURN_PROMISE =
     PRODUCER_FUNCTION_NAME + ERR_MSG_MUST_RETURN_PROMISE;
+
+const MSG_BUILTIN_ERROR_INSTANCE = '`Error` instance.';
+
+export const ERR_MSG_THROWN_VALUE_IS_NOT_BUILTIN_ERROR_INSTANCE =
+    'The thrown value is not an ' + MSG_BUILTIN_ERROR_INSTANCE;
+
+export const ERR_MSG_CONTAINED_TYPE_E_SHOULD_BE_BUILTIN_ERROR_INSTANCE =
+    'The contained E should be ' + MSG_BUILTIN_ERROR_INSTANCE;
diff --git a/src/internal/assert.ts b/src/internal/assert.ts
index 3c12f380..4caa1d5a 100644
--- a/src/internal/assert.ts
+++ b/src/internal/assert.ts
@@ -10,12 +10,13 @@ export function assertIsPromise(
     }
 }
 
-export function assertIsError(input: unknown): asserts input is Error {
-    if (!(input instanceof Error)) {
+export function assertIsErrorInstance(input: unknown, message: string): asserts input is Error {
+    const ok = input instanceof Error;
+    if (!ok) {
         const stringified = String(input);
-        const message = `The input is not an \`Error\` instance. The actual is \`${stringified}\``;
+        const msg = `${message} The actual is \`${stringified}\``;
         // We don't throw Node's AssertionError because the code size will be larger.
-        throw new TypeError(message, {
+        throw new TypeError(msg, {
             cause: input,
         });
     }


Test patch:
diff --git a/__tests__/PlainResult/try_catch/try_catch_with_ensure_error.test.mjs b/__tests__/PlainResult/try_catch/try_catch_with_ensure_error.test.mjs
index 4137bde6..a30e4a96 100644
--- a/__tests__/PlainResult/try_catch/try_catch_with_ensure_error.test.mjs
+++ b/__tests__/PlainResult/try_catch/try_catch_with_ensure_error.test.mjs
@@ -47,7 +47,7 @@ test('If producer throw non-Error-instance value', (t) => {
         },
         {
             instanceOf: TypeError,
-            message: `The input is not an \`Error\` instance. The actual is \`${String(
+            message: `The thrown value is not an \`Error\` instance. The actual is \`${String(
                 EXPECT_THROWN
             )}\``,
         }
diff --git a/__tests__/PlainResult/try_catch_async/try_catch_with_ensure_error_async.test.mjs b/__tests__/PlainResult/try_catch_async/try_catch_with_ensure_error_async.test.mjs
index c02fdd42..6a1cef19 100644
--- a/__tests__/PlainResult/try_catch_async/try_catch_with_ensure_error_async.test.mjs
+++ b/__tests__/PlainResult/try_catch_async/try_catch_with_ensure_error_async.test.mjs
@@ -120,7 +120,7 @@ test('if producer is normal function and reject a Promise with not-Error-instanc
         },
         {
             instanceOf: TypeError,
-            message: `The input is not an \`Error\` instance. The actual is \`${String(
+            message: `The thrown value is not an \`Error\` instance. The actual is \`${String(
                 THROWN_EXPECTED
             )}\``,
         }
@@ -144,7 +144,7 @@ test('if producer is normal function and throw a not-Error-instance value before
         },
         {
             instanceOf: TypeError,
-            message: `The input is not an \`Error\` instance. The actual is \`${String(
+            message: `The thrown value is not an \`Error\` instance. The actual is \`${String(
                 THROWN_EXPECTED
             )}\``,
         }
@@ -168,7 +168,7 @@ test('if producer is async function and throw a not-Error-instance value', async
         },
         {
             instanceOf: TypeError,
-            message: `The input is not an \`Error\` instance. The actual is \`${String(
+            message: `The thrown value is not an \`Error\` instance. The actual is \`${String(
                 THROWN_EXPECTED
             )}\``,
         }
diff --git a/__tests__/PlainResult/unwrap_or_throw_error.test.mjs b/__tests__/PlainResult/unwrap_or_throw_error.test.mjs
index d57529eb..f6b1e6eb 100644
--- a/__tests__/PlainResult/unwrap_or_throw_error.test.mjs
+++ b/__tests__/PlainResult/unwrap_or_throw_error.test.mjs
@@ -41,7 +41,7 @@ test('input is Err, but the contained value is not Error', (t) => {
         },
         {
             instanceOf: TypeError,
-            message: `The contained E should be \`Error\` instance but that was \`${String(
+            message: `The contained E should be \`Error\` instance. The actual is \`${String(
                 ERROR_E
             )}\``,
         }