Skip to content

fix(ios): keep the original error message for script download failures - #1449

Open
yunsung-miso wants to merge 2 commits into
callstack:mainfrom
yunsung-miso:fix/ios-script-download-error-message
Open

fix(ios): keep the original error message for script download failures#1449
yunsung-miso wants to merge 2 commits into
callstack:mainfrom
yunsung-miso:fix/ios-script-download-error-message

Conversation

@yunsung-miso

Copy link
Copy Markdown

Summary

Fixes #1448.

On iOS, every transport-level script download failure reached JavaScript as Unknown error from a native module, so a timeout, a dropped connection and a TLS failure were indistinguishable in production logs.

downloadAndCache hands its NSError to the reject block as error.localizedFailureReason. NSURLError leaves that property nil, and React Native substitutes its own fallback string whenever the message is nil. HTTP status failures were unaffected only because downloadAndCache builds those errors itself and sets NSLocalizedFailureReasonErrorKey explicitly — which is what made the gap easy to miss.

Android already falls back with e.message ?: e.toString() in RemoteScriptLoader.kt, so this brings iOS in line.

Changes

  • Add DescribeScriptDownloadError, which falls back to localizedDescription and appends the error domain and code.
  • Use it at both ScriptDownloadFailure reject sites (loadScript, prefetchScript), and pass the NSError through as the third argument so userInfo survives the bridge.

Before: Unknown error from a native module
After: The request timed out. (NSURLErrorDomain -1001)

Compatibility

The reject code stays ScriptDownloadFailure, so the retry gate in loadScriptWithRetry (LOADING_ERROR_CODES) behaves exactly as before. Only the message and the attached error change.

Test plan

  • Load a remote container or chunk on a connection slow enough to exceed the script timeout (Network Link Conditioner, 3G profile) and confirm the rejection now names the failure.
  • Point a remote at an unreachable host and confirm the domain and code appear.
  • Confirm an HTTP 403 still reports Request should have returned with 200 HTTP status, but instead it received 403.

NSURLError leaves localizedFailureReason nil, so the reject block received a nil
message and React Native replaced it with "Unknown error from a native module".
Every transport-level failure therefore looked identical in production logs.

Fall back to localizedDescription, append the error domain and code, and pass the
NSError through so its userInfo survives. The reject code stays ScriptDownloadFailure,
so the retry gate in loadScriptWithRetry is unaffected.
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@yunsung-miso is attempting to deploy a commit to the Callstack Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2d8fb1e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack Patch
@callstack/repack-plugin-expo-modules Patch
@callstack/repack-plugin-nativewind Patch
@callstack/repack-plugin-reanimated Patch
@callstack/repack-dev-server Patch
@callstack/repack-init Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS: script download errors lose their message (Unknown error from a native module)

1 participant