nitro icon indicating copy to clipboard operation
nitro copied to clipboard

Bug: iOS Error: Unknown std::runtime_error when using react-native-skia

Open kalem-edlin opened this issue 2 months ago • 9 comments

What's happening?

Firstly, this project is awesome!

When @shopify/react-native-skia is added as a dependency and pods are installed, error messages from Swift/C++ native code are no longer propagated correctly to JavaScript. Instead of showing the actual error message, all errors show as "Error: Unknown std::runtime_error error."

I noticed this in my private Expo App (using Expo 53/React Native 0.79.5 initially and persisted in Expo 54/React Native 0.81.4) when none of my error contexts from my own Nitro Module usingRuntimeError.error(withMessage: [custom error message] were propagating to my JS code.

I have easily been able to reproduce this error by adding react-native-skia to the example app of this repo.

This issue was previously mentioned in #382, but that issue was closed. The problem still persists on the latest main branch. Without react-native-skia installed, all tests pass correctly and error messages propagate as expected.

It seems like there might be a conflict in how error handling works when multiple native modules using C++/JSI are present. The error messages are being stripped somewhere in the exception propagation chain when Skia is loaded.

Reproduceable Code

Pull Request

Relevant log output

❌ Test "funcThatThrows() throws" failed!
     Expected: "TestObjectCpp.funcThatThrows(...):"
     Got: "Error: `TestObjectCpp.funcThatThrows(...)` threw an unknown std::runtime_error error."

  ❌ Test "funcThatThrowsBeforePromise() throws" failed!
     Expected: "TestObjectCpp.funcThatThrowsBeforePromise(...):"
     Got: "Error: `TestObjectCpp.funcThatThrowsBeforePromise(...)` threw an unknown std::runtime_error
error."

  ❌ Test "set someVariant to false" failed!
     Expected: "Error: TestObjectCpp.someVariant: Cannot convert "false" to any type in
  variant<std::string, double>!"
     Got: "Error: `TestObjectCpp.someVariant` threw an unknown std::runtime_error error."

  ❌ Test "promiseThrows() throws" failed!
     Expected: "Error: Promise throws :)"
     Got: "Error: Unknown std::runtime_error error."

[... 9 total test failures with same pattern]

Device

iPhone 16 - iOS 18.3.1

Nitro Modules Version

0.29.8

Nitrogen Version

0.29.8

Can you reproduce this issue in the Nitro Example app here?

Yes, I can reproduce the same issue in the Example app here

Additional information

kalem-edlin avatar Oct 07 '25 07:10 kalem-edlin

That is super weird. The issue you mentioned (#382) was closed because we fixed the actual problem in upstream react-native core. The issue was, that -fexceptions was not enabled in react-native core, causing it to also not be enabled in Nitro Modules since those are imported by react-native core, and not always built by it (header vs .cpp file).

Now; react-native-skia really shouldn't affect this anyhow. @wcandillon any ideas?

  1. Can you confirm that adding react-native-skia does not change any dependencies (like react-native core) anyhow?
  2. We probably need to check if react-native-skia has any headers or namespaces that conflict with the Nitro ones. @wcandillon I don't think you use the early prototype of Nitro I sent you back in the day for Skia, right? Only for WebGPU?
  3. Can Skia throw exceptions fine? In Skia code (e.g. some MakeImage... func) can we throw a std::runtime_error and have the message be propagated to JS?
  4. If not, we probably need to enable -fexceptions for react-native-skia

mrousavy avatar Oct 07 '25 10:10 mrousavy

Which platforms did you test btw? I see iOS/Swift, but did you also test Android?

mrousavy avatar Oct 07 '25 10:10 mrousavy

@mrousavy Thanks for cc'ing me on this.

My assumption is that -fexceptions is enabled by default on newer React Native versions (we had to explicitly enable it on Android for older RN versions). But this assumption might be wrong and this should be revisited.

I am not knowledgeable yet on the best practices to throw errors in JSI. Where would be a good place to look at? I'd be happy to align there.

We do not use any margelo/nitro namespaces in Skia or Skia Graphite.

wcandillon avatar Oct 07 '25 11:10 wcandillon

I am not knowledgeable yet on the best practices to throw errors in JSI

Just throw - that's what I do in Nitro too. I just wrap them for better error messages

mrousavy avatar Oct 07 '25 11:10 mrousavy

My assumption is that -fexceptions is enabled by default on newer React Native versions

I think so too, that's why I found this issue to be so confusing.

I'm guessing if this issue can be reproduced here (#920), it's not Expo related, and it's also not an older react-native version.

I just wonder; do you throw any errors in react-native-skia? If yes, does that work fine with error messages and all?

mrousavy avatar Oct 07 '25 11:10 mrousavy

Last time I tried it I was happy with the behavior of the error throwing. There is two kinds of errors: Errors which are thrown directly from a JSI call (on JS or worklet thread) Errors which are from C++ rendering (scene graph)

But could definitely check it again and consolidate things if needed.

wcandillon avatar Oct 07 '25 11:10 wcandillon

I think I'm running into the same issue. The errors work in the example project of @kingstinct/react-native-healthkit (which uses nitro) but not in another project using both react-native-skia and @kingstinct/react-native-healthkit as dependencies (both projects on Expo 54 with Expo-aligned dependencies).

robertherber avatar Nov 14 '25 08:11 robertherber

is this on iOS? Android? both? I think there is a legitimate concern here, I'm just still confused about this topic.

wcandillon avatar Nov 14 '25 09:11 wcandillon

is this on iOS? Android? both? I think there is a legitimate concern here, I'm just still confused about this topic.

In this case iOS only.

I just reproduced the issue by adding react-native-skia to the example app in react-native-healthkit.

robertherber avatar Nov 14 '25 20:11 robertherber

Are there any news on that one? I face the exact same issue, all my exceptions on iOS turn into [Error: Unknown std::runtime_error error.] making it impossible to tell what fails.

g4rb4g3 avatar Dec 04 '25 12:12 g4rb4g3

Could it be related to this one? https://issues.skia.org/issues/316196498 It is from 2023 though... hard to believe but not impossible.

g4rb4g3 avatar Dec 09 '25 20:12 g4rb4g3

wtf, it is indeed that issue... I built skia from sources and copied over the libskia.a and now I get this

Image

instead of

Image

g4rb4g3 avatar Dec 09 '25 21:12 g4rb4g3

closed via https://github.com/Shopify/react-native-skia/pull/3595 - thanks @wcandillon

mrousavy avatar Dec 11 '25 09:12 mrousavy