Skip to content

Commit

Permalink
earlyjs: Implement decoratedExtraDataKey (#46932)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #46932

In the old error handling pipeline, when the app [assigns an object to error[ExceptionsManager.decoratedExtraDataKey]](https://fburl.com/code/9t9u8rgv)

```
        const error = new Error('Some error happened');
        // Annotates the error with some custom extra data.
        error[ExceptionsManager.decoratedExtraDataKey] = {foo: 'bar'};
        ExceptionsManager.handleException(error, true);
```

That object [gets forwarded as extraData](https://fburl.com/code/gy7v173u) to ExceptionsManager.

This diff implements that functionality within the c++ earlyjs pipeline.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D63927091
  • Loading branch information
RSNara authored and facebook-github-bot committed Oct 9, 2024
1 parent b5fc908 commit e0158b9
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 7 deletions.
5 changes: 3 additions & 2 deletions packages/react-native/Libraries/Core/ExceptionsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ type ExceptionDecorator = ExceptionData => ExceptionData;
let userExceptionDecorator: ?ExceptionDecorator;
let inUserExceptionDecorator = false;

// This Symbol is used to decorate an ExtendedError with extra data in select usecases.
// This string is used to decorate an ExtendedError with extra data in select usecases.
// Note that data passed using this method should be strictly contained,
// as data that's not serializable/too large may cause issues with passing the error to the native code.
const decoratedExtraDataKey: symbol = Symbol('decoratedExtraDataKey');
// TODO(T204185517): We should use a Symbol for this, but jsi through jsc doesn't support it yet.
const decoratedExtraDataKey = 'RN$ErrorExtraDataKey';

/**
* Allows the app to add information to the exception report before it is sent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4337,7 +4337,7 @@ exports[`public API should not change unintentionally Libraries/Core/ExceptionsM
name: string;
}
type ExceptionDecorator = (ExceptionData) => ExceptionData;
declare const decoratedExtraDataKey: symbol;
declare const decoratedExtraDataKey: \\"RN$ErrorExtraDataKey\\";
declare function unstable_setExceptionDecorator(
exceptionDecorator: ?ExceptionDecorator
): void;
Expand Down
6 changes: 3 additions & 3 deletions packages/react-native/ReactCommon/jsc/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,9 @@ jsi::PropNameID JSCRuntime::createPropNameIDFromString(const jsi::String& str) {
}

jsi::PropNameID JSCRuntime::createPropNameIDFromSymbol(const jsi::Symbol& sym) {
// TODO: Support for symbols through the native API in JSC is very limited.
// While we could construct a PropNameID here, we would not be able to get a
// symbol property through the C++ API.
// TODO(T204185517): Support for symbols through the native API in JSC is very
// limited. While we could construct a PropNameID here, we would not be able
// to get a symbol property through the C++ API.
throw std::logic_error("Not implemented");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ bool isTruthy(jsi::Runtime& runtime, const jsi::Value& value) {
auto Boolean = runtime.global().getPropertyAsFunction(runtime, "Boolean");
return Boolean.call(runtime, value).getBool();
}

void objectAssign(
jsi::Runtime& runtime,
jsi::Object& target,
const jsi::Object& value) {
auto Object = runtime.global().getPropertyAsObject(runtime, "Object");
auto assign = Object.getPropertyAsFunction(runtime, "assign");
assign.callWithThis(runtime, Object, target, value);
}
} // namespace

namespace facebook::react {
Expand Down Expand Up @@ -198,8 +207,14 @@ void JsErrorHandler::emitError(
message += ", js engine: " + stringifyToCpp(runtime, jsEngineValue);
}

// TODO: What about spreading in decoratedExtraDataKey?
auto extraDataKey = jsi::PropNameID::forUtf8(runtime, "RN$ErrorExtraDataKey");
auto extraDataValue = errorObj.getProperty(runtime, extraDataKey);

auto extraData = jsi::Object(runtime);
if (extraDataValue.isObject()) {
objectAssign(runtime, extraData, extraDataValue.asObject(runtime));
}

extraData.setProperty(runtime, "jsEngine", jsEngineValue);
extraData.setProperty(runtime, "rawStack", error.getStack());

Expand Down

0 comments on commit e0158b9

Please sign in to comment.