Skip to content

Commit

Permalink
implement node:util.getSystemErrorName() (#12837)
Browse files Browse the repository at this point in the history
  • Loading branch information
nektro authored Jul 27, 2024
1 parent 70ca2b7 commit a0ebb05
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/runtime/nodejs-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Some methods are not optimized yet.

### [`node:util`](https://nodejs.org/api/util.html)

🟡 Missing `MIMEParams` `MIMEType` `aborted` `debug` `getSystemErrorMap` `getSystemErrorName` `transferableAbortController` `transferableAbortSignal` `stripVTControlCharacters`
🟡 Missing `MIMEParams` `MIMEType` `aborted` `debug` `getSystemErrorMap` `transferableAbortController` `transferableAbortSignal` `stripVTControlCharacters`

### [`node:v8`](https://nodejs.org/api/v8.html)

Expand Down
95 changes: 95 additions & 0 deletions src/bun.js/bindings/NodeError.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "root.h"
#include "headers-handwritten.h"
#include "BunClientData.h"
#include "helpers.h"
#include "JavaScriptCore/JSCJSValue.h"
#include "JavaScriptCore/ErrorInstance.h"
#include "JavaScriptCore/ExceptionScope.h"
#include "wtf/text/ASCIILiteral.h"
#include "wtf/text/MakeString.h"
#include <cstdio>

JSC::EncodedJSValue JSC__JSValue__createTypeError(const ZigString* message, const ZigString* arg1, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue JSC__JSValue__createRangeError(const ZigString* message, const ZigString* arg1, JSC::JSGlobalObject* globalObject);

namespace Bun {

using namespace JSC;

JSC::JSValue createTypeErrorWithCode(JSC::JSGlobalObject* globalObject, String message, ASCIILiteral code)
{
JSC::VM& vm = globalObject->vm();

JSC::JSObject* result = JSC::createTypeError(globalObject, message);
JSC::EnsureStillAliveScope ensureAlive(result);
auto typeError = JSC::JSValue(result).asCell()->getObject();

auto clientData = WebCore::clientData(vm);
typeError->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, String(code)), 0);

return typeError;
}

JSC::JSValue createRangeErrorWithCode(JSC::JSGlobalObject* globalObject, String message, ASCIILiteral code)
{
JSC::VM& vm = globalObject->vm();

JSC::JSObject* result = JSC::createRangeError(globalObject, message);
JSC::EnsureStillAliveScope ensureAlive(result);
auto typeError = JSC::JSValue(result).asCell()->getObject();

auto clientData = WebCore::clientData(vm);
typeError->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, String(code)), 0);

return typeError;
}

JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_INVALID_ARG_TYPE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

auto argCount = callFrame->argumentCount();
if (argCount < 3) {
JSC::throwTypeError(globalObject, scope, "requires 3 arguments"_s);
return {};
}

auto arg_name = callFrame->argument(0).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto expected_type = callFrame->argument(1).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto actual_value = callFrame->argument(2).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto message = makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Recieved "_s, actual_value);
return JSC::JSValue::encode(createTypeErrorWithCode(globalObject, message, "ERR_INVALID_ARG_TYPE"_s));
}

JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_OUT_OF_RANGE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

auto argCount = callFrame->argumentCount();
if (argCount < 3) {
JSC::throwTypeError(globalObject, scope, "requires 3 arguments"_s);
return {};
}

auto arg_name = callFrame->argument(0).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto range = callFrame->argument(1).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto input = callFrame->argument(2).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});

auto message = makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received "_s, input);
return JSC::JSValue::encode(createRangeErrorWithCode(globalObject, message, "ERR_OUT_OF_RANGE"_s));
}

}
8 changes: 8 additions & 0 deletions src/bun.js/bindings/NodeError.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "root.h"

namespace Bun {

JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_INVALID_ARG_TYPE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame));
JSC_DEFINE_HOST_FUNCTION(jsFunction_ERR_OUT_OF_RANGE, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame));

}
18 changes: 18 additions & 0 deletions src/bun.js/bindings/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,7 @@ JSC__JSValue WebCore__FetchHeaders__toJS(WebCore__FetchHeaders* headers, JSC__JS

return JSC::JSValue::encode(value);
}

JSC__JSValue WebCore__FetchHeaders__clone(WebCore__FetchHeaders* headers, JSC__JSGlobalObject* arg1)
{
auto throwScope = DECLARE_THROW_SCOPE(arg1->vm());
Expand Down Expand Up @@ -2132,6 +2133,7 @@ JSC__JSPromise* JSC__JSValue__asPromise(JSC__JSValue JSValue0)
JSC::JSValue value = JSC::JSValue::decode(JSValue0);
return JSC::jsDynamicCast<JSC::JSPromise*>(value);
}

JSC__JSValue JSC__JSValue__createInternalPromise(JSC__JSGlobalObject* globalObject)
{
JSC::VM& vm = globalObject->vm();
Expand Down Expand Up @@ -2192,6 +2194,7 @@ JSC__JSValue JSC__JSPromise__asValue(JSC__JSPromise* arg0, JSC__JSGlobalObject*
ASSERT_WITH_MESSAGE(value.inherits<JSC::JSPromise>(), "JSPromise::asValue() called on a non-promise object");
return JSC::JSValue::encode(value);
}

JSC__JSPromise* JSC__JSPromise__create(JSC__JSGlobalObject* arg0)
{
return JSC::JSPromise::create(arg0->vm(), arg0->promiseStructure());
Expand Down Expand Up @@ -2232,6 +2235,7 @@ JSC__JSValue JSC__JSGlobalObject__getCachedObject(JSC__JSGlobalObject* globalObj
JSC::JSValue result = globalObject->getIfPropertyExists(globalObject, ident);
return JSC::JSValue::encode(result);
}

JSC__JSValue JSC__JSGlobalObject__putCachedObject(JSC__JSGlobalObject* globalObject, const ZigString* arg1, JSC__JSValue JSValue2)
{
JSC::VM& vm = globalObject->vm();
Expand Down Expand Up @@ -2473,6 +2477,7 @@ JSC__Exception* JSC__Exception__create(JSC__JSGlobalObject* arg0, JSC__JSObject*
? JSC::Exception::StackCaptureAction::CaptureStack
: JSC::Exception::StackCaptureAction::DoNotCaptureStack);
}

JSC__JSValue JSC__Exception__value(JSC__Exception* arg0)
{
return JSC::JSValue::encode(arg0->value());
Expand All @@ -2485,17 +2490,20 @@ JSC__JSValue JSC__Exception__value(JSC__Exception* arg0)
// JSC__PropertyNameArray__next(JSC__PropertyNameArray* arg0, size_t arg1);
// CPP_DECL void JSC__PropertyNameArray__release(JSC__PropertyNameArray* arg0);
size_t JSC__JSObject__getArrayLength(JSC__JSObject* arg0) { return arg0->getArrayLength(); }

JSC__JSValue JSC__JSObject__getIndex(JSC__JSValue jsValue, JSC__JSGlobalObject* arg1,
uint32_t arg3)
{
return JSC::JSValue::encode(JSC::JSValue::decode(jsValue).toObject(arg1)->getIndex(arg1, arg3));
}

JSC__JSValue JSC__JSValue__getDirectIndex(JSC__JSValue jsValue, JSC__JSGlobalObject* arg1,
uint32_t arg3)
{
JSC::JSObject* object = JSC::JSValue::decode(jsValue).getObject();
return JSC::JSValue::encode(object->getDirectIndex(arg1, arg3));
}

JSC__JSValue JSC__JSObject__getDirect(JSC__JSObject* arg0, JSC__JSGlobalObject* arg1,
const ZigString* arg2)
{
Expand Down Expand Up @@ -2530,6 +2538,7 @@ bool JSC__JSString__eql(const JSC__JSString* arg0, JSC__JSGlobalObject* obj, JSC
}
bool JSC__JSString__is8Bit(const JSC__JSString* arg0) { return arg0->is8Bit(); };
size_t JSC__JSString__length(const JSC__JSString* arg0) { return arg0->length(); }

JSC__JSObject* JSC__JSString__toObject(JSC__JSString* arg0, JSC__JSGlobalObject* arg1)
{
return arg0->toObject(arg1);
Expand All @@ -2551,6 +2560,7 @@ extern "C" JSC::JSInternalPromise* JSModuleLoader__import(JSC::JSGlobalObject* g
RETURN_IF_EXCEPTION(scope, nullptr);
return promise;
}

JSC__JSValue JSC__JSModuleLoader__evaluate(JSC__JSGlobalObject* globalObject, const unsigned char* arg1,
size_t arg2, const unsigned char* originUrlPtr, size_t originURLLen, const unsigned char* referrerUrlPtr, size_t referrerUrlLen,
JSC__JSValue JSValue5, JSC__JSValue* arg6)
Expand Down Expand Up @@ -2625,6 +2635,7 @@ JSC__JSValue JSC__JSValue__createRangeError(const ZigString* message, const ZigS

return JSC::JSValue::encode(rangeError);
}

JSC__JSValue JSC__JSValue__createTypeError(const ZigString* message, const ZigString* arg1,
JSC__JSGlobalObject* globalObject)
{
Expand Down Expand Up @@ -3083,6 +3094,7 @@ void JSC__JSPromise__rejectAsHandledException(JSC__JSPromise* arg0, JSC__JSGloba
{
arg0->rejectAsHandled(arg1, arg2);
}

JSC__JSPromise* JSC__JSPromise__rejectedPromise(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1)
{
return JSC::JSPromise::rejectedPromise(arg0, JSC::JSValue::decode(JSValue1));
Expand Down Expand Up @@ -3148,6 +3160,7 @@ void JSC__JSPromise__rejectOnNextTickWithHandled(JSC__JSPromise* promise, JSC__J
RETURN_IF_EXCEPTION(scope, void());
}
}

JSC__JSPromise* JSC__JSPromise__resolvedPromise(JSC__JSGlobalObject* globalObject, JSC__JSValue JSValue1)
{
JSC::VM& vm = globalObject->vm();
Expand Down Expand Up @@ -3236,6 +3249,7 @@ void JSC__JSInternalPromise__rejectAsHandledException(JSC__JSInternalPromise* ar
{
arg0->rejectAsHandled(arg1, arg2);
}

JSC__JSInternalPromise* JSC__JSInternalPromise__rejectedPromise(JSC__JSGlobalObject* arg0,
JSC__JSValue JSValue1)
{
Expand All @@ -3248,6 +3262,7 @@ void JSC__JSInternalPromise__resolve(JSC__JSInternalPromise* arg0, JSC__JSGlobal
{
arg0->resolve(arg1, JSC::JSValue::decode(JSValue2));
}

JSC__JSInternalPromise* JSC__JSInternalPromise__resolvedPromise(JSC__JSGlobalObject* arg0,
JSC__JSValue JSValue1)
{
Expand Down Expand Up @@ -3493,6 +3508,7 @@ bool JSC__JSValue__isUndefinedOrNull(JSC__JSValue JSValue0)
{
return JSC::JSValue::decode(JSValue0).isUndefinedOrNull();
}

JSC__JSValue JSC__JSValue__jsBoolean(bool arg0)
{
return JSC::JSValue::encode(JSC::jsBoolean(arg0));
Expand All @@ -3501,6 +3517,7 @@ JSC__JSValue JSC__JSValue__jsDoubleNumber(double arg0)
{
return JSC::JSValue::encode(JSC::jsNumber(arg0));
}

JSC__JSValue JSC__JSValue__jsEmptyString(JSC__JSGlobalObject* arg0)
{
return JSC::JSValue::encode(JSC::jsEmptyString(arg0->vm()));
Expand Down Expand Up @@ -4918,6 +4935,7 @@ JSC__JSValue JSC__JSPromise__rejectedPromiseValue(JSC__JSGlobalObject* globalObj
JSC::ensureStillAliveHere(JSC::JSValue::decode(JSValue1));
return JSC::JSValue::encode(promise);
}

JSC__JSValue JSC__JSPromise__resolvedPromiseValue(JSC__JSGlobalObject* globalObject,
JSC__JSValue JSValue1)
{
Expand Down
108 changes: 108 additions & 0 deletions src/bun.js/node/node_util_binding.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
const std = @import("std");
const bun = @import("root").bun;
const Environment = bun.Environment;
const JSC = bun.JSC;
const string = bun.string;
const Output = bun.Output;
const ZigString = JSC.ZigString;
const uv = bun.windows.libuv;

pub fn internalErrorName(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
const arguments = callframe.arguments(1).slice();
if (arguments.len < 1) {
globalThis.throwNotEnoughArguments("internalErrorName", 1, arguments.len);
return .zero;
}

const err_value = arguments[0];
const err_int = err_value.toInt32();

if (err_int == -4095) return ZigString.static("EOF").toJS(globalThis);
if (err_int == -4094) return ZigString.static("UNKNOWN").toJS(globalThis);
if (err_int == -3000) return ZigString.static("EAI_ADDRFAMILY").toJS(globalThis);
if (err_int == -3001) return ZigString.static("EAI_AGAIN").toJS(globalThis);
if (err_int == -3002) return ZigString.static("EAI_BADFLAGS").toJS(globalThis);
if (err_int == -3003) return ZigString.static("EAI_CANCELED").toJS(globalThis);
if (err_int == -3004) return ZigString.static("EAI_FAIL").toJS(globalThis);
if (err_int == -3005) return ZigString.static("EAI_FAMILY").toJS(globalThis);
if (err_int == -3006) return ZigString.static("EAI_MEMORY").toJS(globalThis);
if (err_int == -3007) return ZigString.static("EAI_NODATA").toJS(globalThis);
if (err_int == -3008) return ZigString.static("EAI_NONAME").toJS(globalThis);
if (err_int == -3009) return ZigString.static("EAI_OVERFLOW").toJS(globalThis);
if (err_int == -3010) return ZigString.static("EAI_SERVICE").toJS(globalThis);
if (err_int == -3011) return ZigString.static("EAI_SOCKTYPE").toJS(globalThis);
if (err_int == -3013) return ZigString.static("EAI_BADHINTS").toJS(globalThis);
if (err_int == -3014) return ZigString.static("EAI_PROTOCOL").toJS(globalThis);

if (err_int == -bun.C.UV_E2BIG) return ZigString.static("E2BIG").toJS(globalThis);
if (err_int == -bun.C.UV_EACCES) return ZigString.static("EACCES").toJS(globalThis);
if (err_int == -bun.C.UV_EADDRINUSE) return ZigString.static("EADDRINUSE").toJS(globalThis);
if (err_int == -bun.C.UV_EADDRNOTAVAIL) return ZigString.static("EADDRNOTAVAIL").toJS(globalThis);
if (err_int == -bun.C.UV_EAFNOSUPPORT) return ZigString.static("EAFNOSUPPORT").toJS(globalThis);
if (err_int == -bun.C.UV_EAGAIN) return ZigString.static("EAGAIN").toJS(globalThis);
if (err_int == -bun.C.UV_EALREADY) return ZigString.static("EALREADY").toJS(globalThis);
if (err_int == -bun.C.UV_EBADF) return ZigString.static("EBADF").toJS(globalThis);
if (err_int == -bun.C.UV_EBUSY) return ZigString.static("EBUSY").toJS(globalThis);
if (err_int == -bun.C.UV_ECANCELED) return ZigString.static("ECANCELED").toJS(globalThis);
if (err_int == -bun.C.UV_ECHARSET) return ZigString.static("ECHARSET").toJS(globalThis);
if (err_int == -bun.C.UV_ECONNABORTED) return ZigString.static("ECONNABORTED").toJS(globalThis);
if (err_int == -bun.C.UV_ECONNREFUSED) return ZigString.static("ECONNREFUSED").toJS(globalThis);
if (err_int == -bun.C.UV_ECONNRESET) return ZigString.static("ECONNRESET").toJS(globalThis);
if (err_int == -bun.C.UV_EDESTADDRREQ) return ZigString.static("EDESTADDRREQ").toJS(globalThis);
if (err_int == -bun.C.UV_EEXIST) return ZigString.static("EEXIST").toJS(globalThis);
if (err_int == -bun.C.UV_EFAULT) return ZigString.static("EFAULT").toJS(globalThis);
if (err_int == -bun.C.UV_EHOSTUNREACH) return ZigString.static("EHOSTUNREACH").toJS(globalThis);
if (err_int == -bun.C.UV_EINTR) return ZigString.static("EINTR").toJS(globalThis);
if (err_int == -bun.C.UV_EINVAL) return ZigString.static("EINVAL").toJS(globalThis);
if (err_int == -bun.C.UV_EIO) return ZigString.static("EIO").toJS(globalThis);
if (err_int == -bun.C.UV_EISCONN) return ZigString.static("EISCONN").toJS(globalThis);
if (err_int == -bun.C.UV_EISDIR) return ZigString.static("EISDIR").toJS(globalThis);
if (err_int == -bun.C.UV_ELOOP) return ZigString.static("ELOOP").toJS(globalThis);
if (err_int == -bun.C.UV_EMFILE) return ZigString.static("EMFILE").toJS(globalThis);
if (err_int == -bun.C.UV_EMSGSIZE) return ZigString.static("EMSGSIZE").toJS(globalThis);
if (err_int == -bun.C.UV_ENAMETOOLONG) return ZigString.static("ENAMETOOLONG").toJS(globalThis);
if (err_int == -bun.C.UV_ENETDOWN) return ZigString.static("ENETDOWN").toJS(globalThis);
if (err_int == -bun.C.UV_ENETUNREACH) return ZigString.static("ENETUNREACH").toJS(globalThis);
if (err_int == -bun.C.UV_ENFILE) return ZigString.static("ENFILE").toJS(globalThis);
if (err_int == -bun.C.UV_ENOBUFS) return ZigString.static("ENOBUFS").toJS(globalThis);
if (err_int == -bun.C.UV_ENODEV) return ZigString.static("ENODEV").toJS(globalThis);
if (err_int == -bun.C.UV_ENOENT) return ZigString.static("ENOENT").toJS(globalThis);
if (err_int == -bun.C.UV_ENOMEM) return ZigString.static("ENOMEM").toJS(globalThis);
if (err_int == -bun.C.UV_ENONET) return ZigString.static("ENONET").toJS(globalThis);
if (err_int == -bun.C.UV_ENOSPC) return ZigString.static("ENOSPC").toJS(globalThis);
if (err_int == -bun.C.UV_ENOSYS) return ZigString.static("ENOSYS").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTCONN) return ZigString.static("ENOTCONN").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTDIR) return ZigString.static("ENOTDIR").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTEMPTY) return ZigString.static("ENOTEMPTY").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTSOCK) return ZigString.static("ENOTSOCK").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTSUP) return ZigString.static("ENOTSUP").toJS(globalThis);
if (err_int == -bun.C.UV_EPERM) return ZigString.static("EPERM").toJS(globalThis);
if (err_int == -bun.C.UV_EPIPE) return ZigString.static("EPIPE").toJS(globalThis);
if (err_int == -bun.C.UV_EPROTO) return ZigString.static("EPROTO").toJS(globalThis);
if (err_int == -bun.C.UV_EPROTONOSUPPORT) return ZigString.static("EPROTONOSUPPORT").toJS(globalThis);
if (err_int == -bun.C.UV_EPROTOTYPE) return ZigString.static("EPROTOTYPE").toJS(globalThis);
if (err_int == -bun.C.UV_EROFS) return ZigString.static("EROFS").toJS(globalThis);
if (err_int == -bun.C.UV_ESHUTDOWN) return ZigString.static("ESHUTDOWN").toJS(globalThis);
if (err_int == -bun.C.UV_ESPIPE) return ZigString.static("ESPIPE").toJS(globalThis);
if (err_int == -bun.C.UV_ESRCH) return ZigString.static("ESRCH").toJS(globalThis);
if (err_int == -bun.C.UV_ETIMEDOUT) return ZigString.static("ETIMEDOUT").toJS(globalThis);
if (err_int == -bun.C.UV_ETXTBSY) return ZigString.static("ETXTBSY").toJS(globalThis);
if (err_int == -bun.C.UV_EXDEV) return ZigString.static("EXDEV").toJS(globalThis);
if (err_int == -bun.C.UV_EFBIG) return ZigString.static("EFBIG").toJS(globalThis);
if (err_int == -bun.C.UV_ENOPROTOOPT) return ZigString.static("ENOPROTOOPT").toJS(globalThis);
if (err_int == -bun.C.UV_ERANGE) return ZigString.static("ERANGE").toJS(globalThis);
if (err_int == -bun.C.UV_ENXIO) return ZigString.static("ENXIO").toJS(globalThis);
if (err_int == -bun.C.UV_EMLINK) return ZigString.static("EMLINK").toJS(globalThis);
if (err_int == -bun.C.UV_EHOSTDOWN) return ZigString.static("EHOSTDOWN").toJS(globalThis);
if (err_int == -bun.C.UV_EREMOTEIO) return ZigString.static("EREMOTEIO").toJS(globalThis);
if (err_int == -bun.C.UV_ENOTTY) return ZigString.static("ENOTTY").toJS(globalThis);
if (err_int == -bun.C.UV_EFTYPE) return ZigString.static("EFTYPE").toJS(globalThis);
if (err_int == -bun.C.UV_EILSEQ) return ZigString.static("EILSEQ").toJS(globalThis);
if (err_int == -bun.C.UV_EOVERFLOW) return ZigString.static("EOVERFLOW").toJS(globalThis);
if (err_int == -bun.C.UV_ESOCKTNOSUPPORT) return ZigString.static("ESOCKTNOSUPPORT").toJS(globalThis);
if (err_int == -bun.C.UV_ENODATA) return ZigString.static("ENODATA").toJS(globalThis);
if (err_int == -bun.C.UV_EUNATCH) return ZigString.static("EUNATCH").toJS(globalThis);

const fmtstring = bun.String.createFormat("Unknown system error {d}", .{err_int}) catch bun.outOfMemory();
return fmtstring.toJS(globalThis);
}
Loading

0 comments on commit a0ebb05

Please sign in to comment.