Skip to content

Commit

Permalink
Make startup errors in the websocket executor invalidate the bridge
Browse files Browse the repository at this point in the history
Reviewed By: mhorowitz

Differential Revision: D5226936

fbshipit-source-id: b6d605974674d0e6f86559f2583553e3636d389b
  • Loading branch information
javache authored and facebook-github-bot committed Jun 22, 2017
1 parent 5026040 commit c5004d5
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Libraries/WebSocket/RCTWebSocketExecutor.m
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ - (void)sendMessage:(NSDictionary<NSString *, id> *)message onReply:(RCTWSMessag

- (void)executeApplicationScript:(NSData *)script sourceURL:(NSURL *)URL onComplete:(RCTJavaScriptCompleteBlock)onComplete
{
// Hack: the bridge transitions out of loading state as soon as this method returns, which prevents us
// from completely invalidating the bridge and preventing an endless barage of RCTLog.logIfNoNativeHook
// calls if the JS execution environment is broken. We therefore block this thread until this message has returned.
dispatch_semaphore_t scriptSem = dispatch_semaphore_create(0);

NSDictionary<NSString *, id> *message = @{
@"method": @"executeApplicationScript",
@"url": RCTNullIfNil(URL.absoluteString),
Expand All @@ -184,7 +189,10 @@ - (void)executeApplicationScript:(NSData *)script sourceURL:(NSURL *)URL onCompl
NSString *error = reply[@"error"];
onComplete(error ? RCTErrorWithMessage(error) : nil);
}
dispatch_semaphore_signal(scriptSem);
}];

dispatch_semaphore_wait(scriptSem, DISPATCH_TIME_FOREVER);
}

- (void)flushedQueue:(RCTJavaScriptCallback)onComplete
Expand Down
6 changes: 5 additions & 1 deletion React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,11 @@ - (void)enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray
// ensureOnJavaScriptThread may execute immediately, so use jsMessageThread, to make sure
// the block is invoked after callJSFunction
if (completion) {
self->_jsMessageThread->runOnQueue(completion);
if (self->_jsMessageThread) {
self->_jsMessageThread->runOnQueue(completion);
} else {
RCTLogWarn(@"Can't invoke completion without messageThread");
}
}
}
}];
Expand Down

0 comments on commit c5004d5

Please sign in to comment.