/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include namespace facebook::react { class JsErrorHandler { public: struct ParsedError { struct StackFrame { std::optional file; std::string methodName; std::optional lineNumber; std::optional column; friend std::ostream& operator<<( std::ostream& os, const StackFrame& frame); }; std::string message; std::optional originalMessage; std::optional name; std::optional componentStack; std::vector stack; int id; bool isFatal; jsi::Object extraData; friend std::ostream& operator<<(std::ostream& os, const ParsedError& error); }; using OnJsError = std::function; explicit JsErrorHandler(OnJsError onJsError); ~JsErrorHandler(); void handleError( jsi::Runtime& runtime, jsi::JSError& error, bool isFatal, bool logToConsole = true); bool hasHandledFatalError(); void registerErrorListener( const std::function& listener); void setRuntimeReady(); bool isRuntimeReady(); void notifyOfFatalError(); bool inErrorHandler(); private: /** * This callback: * 1. Shouldn't retain the ReactInstance. So that we don't get retain cycles. * 2. Should be implemented by something that can outlive the react instance * (both before init and after teardown). So that errors during init and * teardown get reported properly. **/ OnJsError _onJsError; bool _hasHandledFatalError{}; bool _isRuntimeReady{}; std::shared_ptr _inErrorHandler; std::vector> _errorListeners; void handleErrorWithCppPipeline( jsi::Runtime& runtime, jsi::JSError& error, bool isFatal, bool logToConsole); }; } // namespace facebook::react