Skip to content

fix(ios): catch NSException inside completionBlock to prevent TurboModule crash#439

Open
jtyreman-skewb wants to merge 1 commit intobamlab:masterfrom
jtyreman-skewb:fix/ios-catch-exception-in-completion-block
Open

fix(ios): catch NSException inside completionBlock to prevent TurboModule crash#439
jtyreman-skewb wants to merge 1 commit intobamlab:masterfrom
jtyreman-skewb:fix/ios-catch-exception-in-completion-block

Conversation

@jtyreman-skewb
Copy link
Copy Markdown

Problem

In ios/ImageResizer.mm, transformImage() is called inside the completionBlock of loadImageWithURLRequest:, which executes asynchronously on a background thread. transformImage can throw an NSException (for example when saveImage returns NO under memory pressure). This exception is not caught by the outer @try/@catch (which only wraps the synchronous setup code before loadImageWithURLRequest: is called).

When the exception escapes the block, React Native's RCTTurboModule machinery calls convertNSExceptionToJSError from the wrong thread, which then attempts to access Hermes JSI state, causing an EXC_BAD_ACCESS hard crash.

Stack trace seen in production (React Native 0.83.2 / New Architecture):

Fatal Exception: NSException
0  ImageResizer                 transformImage(...)
1  ImageResizer                 -[ImageResizer createResizedImage:...]_block_invoke
2  RCTTurboModule               convertNSExceptionToJSError
3  JavaScriptCore / Hermes      EXC_BAD_ACCESS

Fix

Wrap the transformImage call inside the completion block with its own @try/@catch so any exception is caught and forwarded to the JS reject callback rather than propagating into the TurboModule layer.

This mirrors the pattern already used in the outer scope and is consistent with how other RCT modules handle async completion handlers.

Testing

  • Trigger a low-memory condition while resizing an image (or pass an unsupported format) — the JS catch block now receives the error instead of the app crashing.
  • No regression in the normal resize path.

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.

1 participant