in src/bun.js/bindings/bindings.cpp [4370:4551]
static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global,
JSC::ErrorInstance* err, const Vector<JSC::StackFrame>* stackTrace,
JSC::JSValue val)
{
JSC::JSObject* obj = JSC::jsDynamicCast<JSC::JSObject*>(val);
JSC::VM& vm = global->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
bool getFromSourceURL = false;
if (stackTrace != nullptr && stackTrace->size() > 0) {
populateStackTrace(vm, *stackTrace, &except->stack);
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
} else if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) {
populateStackTrace(vm, *err->stackTrace(), &except->stack);
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
} else {
getFromSourceURL = true;
}
except->code = (unsigned char)err->errorType();
if (err->isStackOverflowError()) {
except->code = 253;
}
if (err->isOutOfMemoryError()) {
except->code = 8;
}
if (except->code == SYNTAX_ERROR_CODE) {
except->message = Bun::toStringRef(err->sanitizedMessageString(global));
} else if (JSC::JSValue message = obj->getIfPropertyExists(global, vm.propertyNames->message)) {
except->message = Bun::toStringRef(global, message);
} else {
except->message = Bun::toStringRef(err->sanitizedMessageString(global));
}
except->name = Bun::toStringRef(err->sanitizedNameString(global));
except->runtime_type = err->runtimeTypeForCause();
const auto& names = builtinNames(vm);
if (except->code != SYNTAX_ERROR_CODE) {
if (JSC::JSValue syscall = obj->getIfPropertyExists(global, names.syscallPublicName())) {
if (syscall.isString()) {
except->syscall = Bun::toStringRef(global, syscall);
}
}
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
if (JSC::JSValue code = obj->getIfPropertyExists(global, names.codePublicName())) {
if (code.isString() || code.isNumber()) {
except->code_ = Bun::toStringRef(global, code);
}
}
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
if (JSC::JSValue path = obj->getIfPropertyExists(global, names.pathPublicName())) {
if (path.isString()) {
except->path = Bun::toStringRef(global, path);
}
}
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
if (JSC::JSValue fd = obj->getIfPropertyExists(global, names.fdPublicName())) {
if (fd.isNumber()) {
except->fd = fd.toInt32(global);
}
}
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
if (JSC::JSValue errno_ = obj->getIfPropertyExists(global, names.errnoPublicName())) {
if (errno_.isNumber()) {
except->errno_ = errno_.toInt32(global);
}
}
if (UNLIKELY(scope.exception())) {
scope.clearExceptionExceptTermination();
}
}
if (getFromSourceURL) {
// we don't want to serialize JSC::StackFrame longer than we need to
// so in this case, we parse the stack trace as a string
if (JSC::JSValue stackValue = obj->getIfPropertyExists(global, vm.propertyNames->stack)) {
if (stackValue.isString()) {
WTF::String stack = stackValue.toWTFString(global);
V8StackTraceIterator iterator(stack);
const uint8_t frame_count = except->stack.frames_len;
except->stack.frames_len = 0;
iterator.forEachFrame([&](const V8StackTraceIterator::StackFrame& frame, bool& stop) -> void {
ASSERT(except->stack.frames_len < frame_count);
auto& current = except->stack.frames_ptr[except->stack.frames_len];
current = {};
String functionName = frame.functionName.toString();
String sourceURL = frame.sourceURL.toString();
current.function_name = Bun::toStringRef(functionName);
current.source_url = Bun::toStringRef(sourceURL);
current.position.line_zero_based = frame.lineNumber.zeroBasedInt();
current.position.column_zero_based = frame.columnNumber.zeroBasedInt();
current.remapped = true;
if (frame.isConstructor) {
current.code_type = ZigStackFrameCodeConstructor;
} else if (frame.isGlobalCode) {
current.code_type = ZigStackFrameCodeGlobal;
}
except->stack.frames_len += 1;
stop = except->stack.frames_len >= frame_count;
});
if (except->stack.frames_len > 0) {
getFromSourceURL = false;
except->remapped = true;
} else {
except->stack.frames_len = frame_count;
}
}
}
if (getFromSourceURL) {
if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, vm.propertyNames->sourceURL)) {
if (sourceURL.isString()) {
except->stack.frames_ptr[0].source_url = Bun::toStringRef(global, sourceURL);
if (JSC::JSValue column = obj->getIfPropertyExists(global, vm.propertyNames->column)) {
if (column.isNumber()) {
except->stack.frames_ptr[0].position.column_zero_based = OrdinalNumber::fromOneBasedInt(column.toInt32(global)).zeroBasedInt();
}
}
if (JSC::JSValue line = obj->getIfPropertyExists(global, vm.propertyNames->line)) {
if (line.isNumber()) {
except->stack.frames_ptr[0].position.line_zero_based = OrdinalNumber::fromOneBasedInt(line.toInt32(global)).zeroBasedInt();
if (JSC::JSValue lineText = obj->getIfPropertyExists(global, names.lineTextPublicName())) {
if (lineText.isString()) {
if (JSC::JSString* jsStr = lineText.toStringOrNull(global)) {
auto str = jsStr->value(global);
except->stack.source_lines_ptr[0] = Bun::toStringRef(str);
except->stack.source_lines_numbers[0] = except->stack.frames_ptr[0].position.line();
except->stack.source_lines_len = 1;
except->remapped = true;
}
}
}
}
}
except->stack.frames_len = 1;
except->stack.frames_ptr[0].remapped = obj->hasProperty(global, names.originalLinePublicName());
}
}
}
}
except->exception = err;
}