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:
John Knox
2019-02-14 06:21:28 -08:00
committed by Facebook Github Bot
parent c0b5f10693
commit 9b6db1f482
4 changed files with 95 additions and 18 deletions

View File

@@ -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
* file in the root directory of this source tree.
*
*/
#import <Foundation/Foundation.h>
#import "SKMacros.h"
#import "FlipperResponder.h"
SK_EXTERN_C_BEGIN
void FlipperPerformBlockOnMainThread(void(^block)());
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder);
SK_EXTERN_C_END
@protocol FlipperConnection;

View File

@@ -7,12 +7,27 @@
*/
#import <Foundation/Foundation.h>
#import "FlipperPlugin.h"
#import "FlipperResponder.h"
void FlipperPerformBlockOnMainThread(void(^block)())
void FlipperPerformBlockOnMainThread(void(^block)(), id<FlipperResponder> responder)
{
if ([NSThread isMainThread]) {
@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"}];
}
} 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"}];
}
});
}
}

View 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

View File

@@ -84,11 +84,11 @@
__weak FlipperKitLayoutPlugin *weakSelf = self;
[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) {
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; });
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; }, responder);
}];
[connection receive:@"setData" withBlock:^(NSDictionary *params, id<FlipperResponder> responder) {
@@ -97,27 +97,27 @@
withPath: params[@"path"]
toValue: params[@"value"]
withConnection: connection];
});
}, 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) {
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) {
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallIsSearchActiveWithConnection: responder]; });
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallIsSearchActiveWithConnection: responder]; }, 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) {
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; });
FlipperPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; }, responder);
}];
}