@@ -26,6 +26,20 @@ @interface RCTBridge (RCTTurboModule)
2626static NSURLSession * (^_urlSessionFactory)(void ) = nil ;
2727static NSURLSession *_cachedURLSession = nil ;
2828
29+ // NSURLError instances fill in localizedDescription but leave localizedFailureReason nil.
30+ // Passing a nil message to the reject block makes React Native substitute
31+ // "Unknown error from a native module", which hides whether the download timed out,
32+ // lost the connection or failed TLS. Fall back to the description and append the
33+ // domain/code so the cause survives the bridge.
34+ static NSString *DescribeScriptDownloadError (NSError *error)
35+ {
36+ NSString *reason = error.localizedFailureReason ?: error.localizedDescription ;
37+ if (reason.length == 0 ) {
38+ reason = @" Script download failed" ;
39+ }
40+ return [NSString stringWithFormat: @" %@ (%@ %ld )" , reason, error.domain, (long )error.code];
41+ }
42+
2943@implementation ScriptManager
3044
3145RCT_EXPORT_MODULE ()
@@ -88,7 +102,7 @@ - (NSURLSession *)urlSession
88102 [self downloadAndCache: config
89103 completionHandler: ^(NSError *error) {
90104 if (error) {
91- reject (ScriptDownloadFailure, error. localizedFailureReason , nil );
105+ reject (ScriptDownloadFailure, DescribeScriptDownloadError ( error), error );
92106 } else {
93107 [self execute: config resolve: resolve reject: reject];
94108 }
@@ -139,7 +153,7 @@ - (NSURLSession *)urlSession
139153 [self downloadAndCache: config
140154 completionHandler: ^(NSError *error) {
141155 if (error) {
142- reject (ScriptDownloadFailure, error. localizedFailureReason , nil );
156+ reject (ScriptDownloadFailure, DescribeScriptDownloadError ( error), error );
143157 } else {
144158 resolve (nil );
145159 }
0 commit comments