aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/ProtoRPC/ProtoRPC.m
diff options
context:
space:
mode:
authorGravatar Robbie Shade <rjshade@google.com>2015-09-14 13:18:14 -0400
committerGravatar Robbie Shade <rjshade@google.com>2015-09-14 13:18:14 -0400
commitf798b779fc35e0be603f07589f3f27efa316da7f (patch)
tree7c9e0b908218f6ed6207139c2065c6b78358fa5a /src/objective-c/ProtoRPC/ProtoRPC.m
parent780b07e6442b06039a936382ce10fe0c4a30f4af (diff)
parent261666696496174f824d9e43a60559040eda3055 (diff)
Merge remote-tracking branch 'upstream/master' into rename_callback
Diffstat (limited to 'src/objective-c/ProtoRPC/ProtoRPC.m')
-rw-r--r--src/objective-c/ProtoRPC/ProtoRPC.m33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m
index 889d71a308..9bf66f347a 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.m
+++ b/src/objective-c/ProtoRPC/ProtoRPC.m
@@ -37,6 +37,22 @@
#import <RxLibrary/GRXWriteable.h>
#import <RxLibrary/GRXWriter+Transformations.h>
+static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) {
+ NSDictionary *info = @{
+ NSLocalizedDescriptionKey: @"Unable to parse response from the server",
+ NSLocalizedRecoverySuggestionErrorKey: @"If this RPC is idempotent, retry "
+ @"with exponential backoff. Otherwise, query the server status before "
+ @"retrying.",
+ NSUnderlyingErrorKey: parsingError,
+ @"Expected class": expectedClass,
+ @"Received value": proto,
+ };
+ // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public.
+ return [NSError errorWithDomain:@"io.grpc"
+ code:13
+ userInfo:info];
+}
+
@implementation ProtoRPC {
id<GRXWriteable> _responseWriteable;
}
@@ -65,14 +81,25 @@
}
// A writer that serializes the proto messages to send.
GRXWriter *bytesWriter = [requestsWriter map:^id(GPBMessage *proto) {
- // TODO(jcanizales): Fail with an understandable error message if the requestsWriter isn't
- // sending GPBMessages.
+ if (![proto isKindOfClass:GPBMessage.class]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Request must be a proto message: %@", proto];
+ }
return [proto data];
}];
if ((self = [super initWithHost:host path:method.HTTPPath requestsWriter:bytesWriter])) {
+ __weak ProtoRPC *weakSelf = self;
+
// A writeable that parses the proto messages received.
_responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- [responsesWriteable writeValue:[responseClass parseFromData:value error:NULL]];
+ // TODO(jcanizales): This is done in the main thread, and needs to happen in another thread.
+ NSError *error = nil;
+ id parsed = [responseClass parseFromData:value error:&error];
+ if (parsed) {
+ [responsesWriteable writeValue:parsed];
+ } else {
+ [weakSelf finishWithError:ErrorForBadProto(value, responseClass, error)];
+ }
} completionHandler:^(NSError *errorOrNil) {
[responsesWriteable writesFinishedWithError:errorOrNil];
}];