Repository: denoland/deno
Pull request: fix(ext/node): implement util.getSystemErrorMessage()

Solution for https://github.com/denoland/deno/issues/31132

Changed files:
filename: ext/node/polyfills/_utils.ts
patch: @@ -17,6 +17,7 @@ import { TextDecoder, TextEncoder } from "ext:deno_web/08_text_encoding.js";
 import { errorMap } from "ext:deno_node/internal_binding/uv.ts";
 import { codes } from "ext:deno_node/internal/error_codes.ts";
 import { ERR_NOT_IMPLEMENTED } from "ext:deno_node/internal/errors.ts";
+import { validateNumber } from "./internal/validators.mjs";
 
 export type BinaryEncodings = "binary";
 
@@ -147,11 +148,21 @@ export function makeMethodsEnumerable(klass: { new (): unknown }) {
  * @param code error code number
  */
 export function getSystemErrorName(code: number): string | undefined {
-  if (typeof code !== "number") {
-    throw new codes.ERR_INVALID_ARG_TYPE("err", "number", code);
-  }
+  validateNumber(code, "err");
   if (code >= 0 || !NumberIsSafeInteger(code)) {
     throw new codes.ERR_OUT_OF_RANGE("err", "a negative integer", code);
   }
   return errorMap.get(code)?.[0];
 }
+
+/**
+ * Returns a system error message from an error code number.
+ * @param code error code number
+ */
+export function getSystemErrorMessage(code: number): string | undefined {
+  validateNumber(code, "err");
+  if (code >= 0 || !NumberIsSafeInteger(code)) {
+    throw new codes.ERR_OUT_OF_RANGE("err", "a negative integer", code);
+  }
+  return errorMap.get(code)?.[1];
+}

filename: ext/node/polyfills/util.ts
patch: @@ -122,6 +122,7 @@ export function inherits<T, U>(
 import {
   _TextDecoder,
   _TextEncoder,
+  getSystemErrorMessage,
   getSystemErrorName,
 } from "ext:deno_node/_utils.ts";
 
@@ -307,7 +308,7 @@ export function getCallSites(
   return capturedTraces;
 }
 
-export { getSystemErrorName, isDeepStrictEqual };
+export { getSystemErrorMessage, getSystemErrorName, isDeepStrictEqual };
 
 export default {
   format,
@@ -316,6 +317,7 @@ export default {
   _extend,
   getCallSites,
   getSystemErrorName,
+  getSystemErrorMessage,
   aborted,
   deprecate,
   callbackify,

filename: tests/unit_node/util_test.ts
patch: @@ -120,6 +120,45 @@ Deno.test({
   },
 });
 
+Deno.test({
+  name: "[util] getSystemErrorMessage()",
+  fn() {
+    type FnTestInvalidArg = (code?: unknown) => void;
+
+    assertThrows(
+      () => (util.getSystemErrorMessage as FnTestInvalidArg)(),
+      TypeError,
+    );
+    assertThrows(
+      () => (util.getSystemErrorMessage as FnTestInvalidArg)(1),
+      RangeError,
+    );
+
+    assertStrictEquals(util.getSystemErrorMessage(-424242), undefined);
+
+    switch (Deno.build.os) {
+      case "windows":
+        assertStrictEquals(
+          util.getSystemErrorMessage(-4091),
+          "address already in use",
+        );
+        break;
+      case "darwin":
+        assertStrictEquals(
+          util.getSystemErrorMessage(-48),
+          "address already in use",
+        );
+        break;
+      case "linux":
+        assertStrictEquals(
+          util.getSystemErrorMessage(-98),
+          "address already in use",
+        );
+        break;
+    }
+  },
+});
+
 Deno.test({
   name: "[util] deprecate() works",
   fn() {