nitro icon indicating copy to clipboard operation
nitro copied to clipboard

Expose more info from native errors

Open robertherber opened this issue 1 month ago • 6 comments

Feature Request/Enhancement

When returning errors (and not explicit runtimeErrors) it seems the it's always just returning a generic error, with no description or metadata. It would be great if all errors exposed as much as possible to the JS side, without needing explicit handling.

Are there any existing workarounds?

No response

Additional information

robertherber avatar Nov 13 '25 08:11 robertherber

Hi - what do you mean with no description or metadata?

When you use the Error type in your HybridObjects you can return an std::exception in C++, Throwable in Kotlin and Error in Swift - they will expose the .what()/.message to JS. Nothing else gets exposed to JS, because I wouldn't know any other properties (std::exception/Error don't have more properties than a message)

mrousavy avatar Nov 13 '25 10:11 mrousavy

So HealthKit exposes an HKError object that includes interesting metadata like errorCode. I'd like this to expose this to the JS side somehow.

Ideally it would be automatic, but being able to extend RuntimeError with metadata is another option.

I see two ways to expose this information on the Swift side, but no way to in turn expose this when throwing the error to the JS side;

The HKError way:

if let error = error as? HKError {
    return continuation.resume(throwing: error)
} else if let error = error {
    return continuation.resume(throwing: error)
}

The NSError way:

let nsError = error as NSError // error is of type Error/HKError
let isHealthKitError = nsError.domain == HKError.errorDomain
let code = nsError.code // (which could be for example HKError.Code.errorNoData.rawValue)

What we're getting now from a HKError directly passed is a JS Error with a message of "Error Domain=com.apple.healthkit Code=5 "Authorization not determined" UserInfo={NSLocalizedDescription=Authorization not determined}". Being able to expose this in a more structured format would be great.

robertherber avatar Nov 14 '25 08:11 robertherber

I understand your problem, but I still don't see what the solution would be - do you have one?

My idea is to add .type and .stacktrace to an Error, as mentioned in https://github.com/mrousavy/nitro/issues/1014.

.code will be hard to expose - we cannot just add dynamic properties to the JS error object.

I think your best bet is to either add it to message (message: "\(code): \(message)").

I guess the last option would be to add metadata as an AnyMap, but I think that would be harder to add and also just a messy combination of untyped keys or values for the user.

mrousavy avatar Nov 14 '25 13:11 mrousavy

Theoritically we have Error.prototype.cause from es2022, but it looks like RN has not used it in tsconfig.

https://github.com/facebook/react-native/blob/e08abbcb99270381c94145a33476f51684dffd93/packages/typescript-config/tsconfig.json#L19-L21

Until now complex error info can only be passed as json string in Error.message, bc the intermediary, std::exception, only has an explanatory string returned by what()

Phecda avatar Nov 14 '25 17:11 Phecda

Using Error.prototype.cause seems like a pretty good way forward to align with JS standards in my opinion. Seems like it's enabled with Expos tsconfig. If using the RN tsconfig it shouldn't cause any runtime issues and be easily overridable for those that want to access it - right?

Having an optional AnyMap cause argument in RuntimeError.error would align pretty well with the JS spec I guess. Unless there's a better way to make this type safe of course, but does even the JS spec expose this possibility?

Taking it one step further would be by default exposing the NSError properties (i.e. errorDomain, code and userInfo) in the cause property. From my example above this seems to already be passed to the JS side - just encoded in the message string.

robertherber avatar Nov 14 '25 21:11 robertherber

Yea I think all that should be possible. I can write a protocol extension for NSError

mrousavy avatar Nov 17 '25 11:11 mrousavy