static void fromErrorInstance()

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;
}