Respond on exceptions thrown when on main thread
Summary: Changes FlipperPerformBlockOnMainThread to take a responder, and respond with an error if an exception is caught. Reviewed By: passy Differential Revision: D14066982 fbshipit-source-id: 70135bf58171684bcd013c66d9deec366aed36f5
This commit is contained in:
committed by
Facebook Github Bot
parent
c0b5f10693
commit
9b6db1f482
@@ -1,16 +1,16 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright (c) 2004-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the MIT license found in the LICENSE
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
* file in the root directory of this source tree.
|
* file in the root directory of this source tree.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "SKMacros.h"
|
#import "SKMacros.h"
|
||||||
|
#import "FlipperResponder.h"
|
||||||
|
|
||||||
|
|
||||||
SK_EXTERN_C_BEGIN
|
SK_EXTERN_C_BEGIN
|
||||||
void FlipperPerformBlockOnMainThread(void(^block)());
|
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder);
|
||||||
SK_EXTERN_C_END
|
SK_EXTERN_C_END
|
||||||
|
|
||||||
@protocol FlipperConnection;
|
@protocol FlipperConnection;
|
||||||
|
|||||||
@@ -7,12 +7,27 @@
|
|||||||
*/
|
*/
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "FlipperPlugin.h"
|
#import "FlipperPlugin.h"
|
||||||
|
#import "FlipperResponder.h"
|
||||||
|
|
||||||
void FlipperPerformBlockOnMainThread(void(^block)())
|
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder)
|
||||||
{
|
{
|
||||||
if ([NSThread isMainThread]) {
|
if ([NSThread isMainThread]) {
|
||||||
|
@try {
|
||||||
block();
|
block();
|
||||||
|
} @catch (NSException *e) {
|
||||||
|
[responder error:@{@"name": e.name, @"message": e.reason}];
|
||||||
|
} @catch (...) {
|
||||||
|
[responder error:@{@"name": @"Unknown", @"message": @"Unknown error caught when processing operation on main thread"}];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatch_async(dispatch_get_main_queue(), block);
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
@try {
|
||||||
|
block();
|
||||||
|
} @catch (NSException *e) {
|
||||||
|
[responder error:@{@"name": e.name, @"message": e.reason}];
|
||||||
|
} @catch (...) {
|
||||||
|
[responder error:@{@"name": @"Unknown", @"message": @"Unknown error caught when processing operation on main thread"}];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
iOS/FlipperKitTests/FlipperUtilTests.mm
Normal file
62
iOS/FlipperKitTests/FlipperUtilTests.mm
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the LICENSE
|
||||||
|
* file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
#if FB_SONARKIT_ENABLED
|
||||||
|
|
||||||
|
#import <FlipperKit/FlipperPlugin.h>
|
||||||
|
#import <FlipperKit/FlipperClient.h>
|
||||||
|
#import <FlipperKit/FlipperClient+Testing.h>
|
||||||
|
#import <FlipperKit/FlipperConnection.h>
|
||||||
|
#import <FlipperKitTestUtils/BlockBasedSonarPlugin.h>
|
||||||
|
#import <FlipperKitTestUtils/FlipperResponderMock.h>
|
||||||
|
#import <FlipperTestLib/FlipperConnectionManagerMock.h>
|
||||||
|
#import <FlipperTestLib/FlipperPluginMock.h>
|
||||||
|
#import <folly/json.h>
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import "FlipperPlugin.h"
|
||||||
|
|
||||||
|
@interface FlipperUtilTests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation FlipperUtilTests {
|
||||||
|
FlipperResponderMock *responder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)setUp {
|
||||||
|
responder = [FlipperResponderMock new];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testPerformOnMainThreadSuccess {
|
||||||
|
FlipperPerformBlockOnMainThread(^{}, responder);
|
||||||
|
NSAssert([responder.successes count] == 0, @"No successes are output");
|
||||||
|
NSAssert([responder.errors count] == 0, @"No errors are output");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testPerformOnMainThreadStdException {
|
||||||
|
FlipperPerformBlockOnMainThread(^{
|
||||||
|
throw new std::exception();
|
||||||
|
}, responder);
|
||||||
|
NSAssert([responder.successes count] == 0, @"No successes are output");
|
||||||
|
NSAssert([responder.errors count] == 1, @"1 error is output");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testPerformOnMainThreadNSException {
|
||||||
|
FlipperPerformBlockOnMainThread(^{
|
||||||
|
NSArray *a = [NSArray init];
|
||||||
|
[a objectAtIndex:1];
|
||||||
|
}, responder);
|
||||||
|
NSAssert([responder.successes count] == 0, @"No successes are output");
|
||||||
|
NSAssert([responder.errors count] == 1, @"1 error is output");
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
@@ -84,11 +84,11 @@
|
|||||||
__weak FlipperKitLayoutPlugin *weakSelf = self;
|
__weak FlipperKitLayoutPlugin *weakSelf = self;
|
||||||
|
|
||||||
[connection receive:@"getRoot" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"getRoot" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetRoot: responder]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetRoot: responder]; }, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"getNodes" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"getNodes" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; }, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"setData" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"setData" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
@@ -97,27 +97,27 @@
|
|||||||
withPath: params[@"path"]
|
withPath: params[@"path"]
|
||||||
toValue: params[@"value"]
|
toValue: params[@"value"]
|
||||||
withConnection: connection];
|
withConnection: connection];
|
||||||
});
|
}, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"setHighlighted" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"setHighlighted" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetHighlighted: params[@"id"] withResponder: responder]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetHighlighted: params[@"id"] withResponder: responder]; }, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"setSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"setSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetSearchActive: [params[@"active"] boolValue] withConnection: connection]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallSetSearchActive: [params[@"active"] boolValue] withConnection: connection]; }, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"isSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"isSearchActive" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallIsSearchActiveWithConnection: responder]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallIsSearchActiveWithConnection: responder]; }, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"isConsoleEnabled" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"isConsoleEnabled" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [responder success: @{@"isEnabled": @NO}];});
|
FlipperPerformBlockOnMainThread(^{ [responder success: @{@"isEnabled": @NO}];}, responder);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[connection receive:@"getSearchResults" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
[connection receive:@"getSearchResults" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
|
||||||
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; });
|
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; }, responder);
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user