aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient
diff options
context:
space:
mode:
Diffstat (limited to 'src/objective-c/GRPCClient')
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.h107
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m21
-rw-r--r--src/objective-c/GRPCClient/private/GRPCRequestHeaders.h52
-rw-r--r--src/objective-c/GRPCClient/private/GRPCRequestHeaders.m119
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.h3
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.m2
-rw-r--r--src/objective-c/GRPCClient/private/NSDictionary+GRPC.m47
-rw-r--r--src/objective-c/GRPCClient/private/NSError+GRPC.h23
8 files changed, 298 insertions, 76 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index 4eda499b1a..35f7e16af7 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -48,11 +48,112 @@
#import <Foundation/Foundation.h>
#import <RxLibrary/GRXWriter.h>
+#pragma mark gRPC errors
+
+// Domain of NSError objects produced by gRPC.
+extern NSString *const kGRPCErrorDomain;
+
+// gRPC error codes.
+// Note that a few of these are never produced by the gRPC libraries, but are of general utility for
+// server applications to produce.
+typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
+ // The operation was cancelled (typically by the caller).
+ GRPCErrorCodeCancelled = 1,
+
+ // Unknown error. Errors raised by APIs that do not return enough error information may be
+ // converted to this error.
+ GRPCErrorCodeUnknown = 2,
+
+ // The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
+ // INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
+ // server (e.g., a malformed file name).
+ GRPCErrorCodeInvalidArgument = 3,
+
+ // Deadline expired before operation could complete. For operations that change the state of the
+ // server, this error may be returned even if the operation has completed successfully. For
+ // example, a successful response from the server could have been delayed long enough for the
+ // deadline to expire.
+ GRPCErrorCodeDeadlineExceeded = 4,
+
+ // Some requested entity (e.g., file or directory) was not found.
+ GRPCErrorCodeNotFound = 5,
+
+ // Some entity that we attempted to create (e.g., file or directory) already exists.
+ GRPCErrorCodeAlreadyExists = 6,
+
+ // The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
+ // used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
+ // those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
+ // (UNAUTHENTICATED is used instead for those errors).
+ GRPCErrorCodePermissionDenied = 7,
+
+ // The request does not have valid authentication credentials for the operation (e.g. the caller's
+ // identity can't be verified).
+ GRPCErrorCodeUnauthenticated = 16,
+
+ // Some resource has been exhausted, perhaps a per-user quota.
+ GRPCErrorCodeResourceExhausted = 8,
+
+ // The RPC was rejected because the server is not in a state required for the procedure's
+ // execution. For example, a directory to be deleted may be non-empty, etc.
+ // The client should not retry until the server state has been explicitly fixed (e.g. by
+ // performing another RPC). The details depend on the service being called, and should be found in
+ // the NSError's userInfo.
+ GRPCErrorCodeFailedPrecondition = 9,
+
+ // The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
+ // transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
+ // modify-write sequence).
+ GRPCErrorCodeAborted = 10,
+
+ // The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
+ // Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
+ // changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
+ // to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
+ // the element at an index past the current size of the list.
+ GRPCErrorCodeOutOfRange = 11,
+
+ // The procedure is not implemented or not supported/enabled in this server.
+ GRPCErrorCodeUnimplemented = 12,
+
+ // Internal error. Means some invariant expected by the server application or the gRPC library has
+ // been broken.
+ GRPCErrorCodeInternal = 13,
+
+ // The server is currently unavailable. This is most likely a transient condition and may be
+ // corrected by retrying with a backoff.
+ GRPCErrorCodeUnavailable = 14,
+
+ // Unrecoverable data loss or corruption.
+ GRPCErrorCodeDataLoss = 15,
+};
+
// Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
// the server.
extern id const kGRPCHeadersKey;
extern id const kGRPCTrailersKey;
+#pragma mark GRPCCall
+
+// The container of the request headers of an RPC conforms to this protocol, which is a subset of
+// NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
+// The keys of this container are the header names, which per the HTTP standard are case-
+// insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
+// can only consist of ASCII characters.
+// A header value is a NSString object (with only ASCII characters), unless the header name has the
+// suffix "-bin", in which case the value has to be a NSData object.
+@protocol GRPCRequestHeaders <NSObject>
+
+@property(nonatomic, readonly) NSUInteger count;
+
+- (id)objectForKeyedSubscript:(NSString *)key;
+- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key;
+
+- (void)removeAllObjects;
+- (void)removeObjectForKey:(NSString *)key;
+
+@end
+
// Represents a single gRPC remote call.
@interface GRPCCall : GRXWriter
@@ -68,10 +169,8 @@ extern id const kGRPCTrailersKey;
//
// After the call is started, trying to modify this property is an error.
//
-// For convenience, the property is initialized to an empty NSMutableDictionary, and the setter
-// accepts (and copies) both mutable and immutable dictionaries.
-- (NSMutableDictionary *)requestHeaders; // nonatomic
-- (void)setRequestHeaders:(NSDictionary *)requestHeaders; // nonatomic, copy
+// The property is initialized to an empty NSMutableDictionary.
+@property(atomic, readonly) id<GRPCRequestHeaders> requestHeaders;
// This dictionary is populated with the HTTP headers received from the server. This happens before
// any response message is received from the server. It has the same structure as the request
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index ff5d1c5aaf..b6986bf59c 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -37,6 +37,7 @@
#include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
+#import "private/GRPCRequestHeaders.h"
#import "private/GRPCWrappedCall.h"
#import "private/NSData+GRPC.h"
#import "private/NSDictionary+GRPC.h"
@@ -93,7 +94,7 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
// the response arrives.
GRPCCall *_retainSelf;
- NSMutableDictionary *_requestHeaders;
+ GRPCRequestHeaders *_requestHeaders;
}
@synthesize state = _state;
@@ -124,21 +125,11 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
_requestWriter = requestWriter;
- _requestHeaders = [NSMutableDictionary dictionary];
+ _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
}
return self;
}
-#pragma mark Metadata
-
-- (NSMutableDictionary *)requestHeaders {
- return _requestHeaders;
-}
-
-- (void)setRequestHeaders:(NSDictionary *)requestHeaders {
- _requestHeaders = [NSMutableDictionary dictionaryWithDictionary:requestHeaders];
-}
-
#pragma mark Finish
- (void)finishWithError:(NSError *)errorOrNil {
@@ -230,10 +221,10 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
#pragma mark Send headers
-- (void)sendHeaders:(NSDictionary *)headers {
+- (void)sendHeaders:(id<GRPCRequestHeaders>)headers {
// TODO(jcanizales): Add error handlers for async failures
- [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc]
- initWithMetadata:headers ?: @{} handler:nil]]];
+ [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc] initWithMetadata:headers
+ handler:nil]]];
}
#pragma mark GRXWriteable implementation
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h
new file mode 100644
index 0000000000..1391b5725f
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#include <grpc/grpc.h>
+
+#import "GRPCCall.h"
+
+@interface GRPCRequestHeaders : NSObject<GRPCRequestHeaders>
+
+@property(nonatomic, readonly) NSUInteger count;
+@property(nonatomic, readonly) grpc_metadata *grpc_metadataArray;
+
+- (instancetype)initWithCall:(GRPCCall *)call;
+
+- (id)objectForKeyedSubscript:(NSString *)key;
+- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key;
+
+- (void)removeAllObjects;
+- (void)removeObjectForKey:(NSString *)key;
+
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
new file mode 100644
index 0000000000..761677ce50
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCRequestHeaders.h"
+
+#import <Foundation/Foundation.h>
+
+#import "../GRPCCall.h"
+#import "NSDictionary+GRPC.h"
+
+// Used by the setter.
+static void CheckIsNonNilASCII(NSString *name, NSString* value) {
+ if (!value) {
+ [NSException raise:NSInvalidArgumentException format:@"%@ cannot be nil", name];
+ }
+ if (![value canBeConvertedToEncoding:NSASCIIStringEncoding]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"%@ %@ contains non-ASCII characters", name, value];
+ }
+}
+
+// Precondition: key isn't nil.
+static void CheckKeyValuePairIsValid(NSString *key, id value) {
+ if ([key hasSuffix:@"-bin"]) {
+ if (![value isKindOfClass:NSData.class]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Expected NSData value for header %@ ending in \"-bin\", "
+ @"instead got %@", key, value];
+ }
+ } else {
+ if (![value isKindOfClass:NSString.class]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Expected NSString value for header %@ not ending in \"-bin\", "
+ @"instead got %@", key, value];
+ }
+ CheckIsNonNilASCII(@"Text header value", (NSString *)value);
+ }
+}
+
+@implementation GRPCRequestHeaders {
+ __weak GRPCCall *_call;
+ NSMutableDictionary *_delegate;
+}
+
+- (instancetype)initWithCall:(GRPCCall *)call {
+ if ((self = [super init])) {
+ _call = call;
+ _delegate = [NSMutableDictionary dictionary];
+ }
+ return self;
+}
+
+- (void)checkCallIsNotStarted {
+ if (_call.state != GRXWriterStateNotStarted) {
+ [NSException raise:@"Invalid modification"
+ format:@"Cannot modify request headers after call is started"];
+ }
+}
+
+- (id)objectForKeyedSubscript:(NSString *)key {
+ return _delegate[key.lowercaseString];
+}
+
+- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key {
+ [self checkCallIsNotStarted];
+ CheckIsNonNilASCII(@"Header name", key);
+ key = key.lowercaseString;
+ CheckKeyValuePairIsValid(key, obj);
+ _delegate[key] = obj;
+}
+
+- (void)removeObjectForKey:(NSString *)key {
+ [self checkCallIsNotStarted];
+ [_delegate removeObjectForKey:key.lowercaseString];
+}
+
+- (void)removeAllObjects {
+ [self checkCallIsNotStarted];
+ [_delegate removeAllObjects];
+}
+
+- (NSUInteger)count {
+ return _delegate.count;
+}
+
+- (grpc_metadata *)grpc_metadataArray {
+ return _delegate.grpc_metadataArray;
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
index da11cbb761..4ca2766147 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h
@@ -35,6 +35,7 @@
#include <grpc/grpc.h>
#import "GRPCChannel.h"
+#import "GRPCRequestHeaders.h"
@interface GRPCOperation : NSObject
@property(nonatomic, readonly) grpc_op op;
@@ -44,7 +45,7 @@
@interface GRPCOpSendMetadata : GRPCOperation
-- (instancetype)initWithMetadata:(NSDictionary *)metadata
+- (instancetype)initWithMetadata:(GRPCRequestHeaders *)metadata
handler:(void(^)())handler NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index fe3d51da53..cea7c479e0 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -65,7 +65,7 @@
return [self initWithMetadata:nil handler:nil];
}
-- (instancetype)initWithMetadata:(NSDictionary *)metadata handler:(void (^)())handler {
+- (instancetype)initWithMetadata:(GRPCRequestHeaders *)metadata handler:(void (^)())handler {
if (self = [super init]) {
_op.op = GRPC_OP_SEND_INITIAL_METADATA;
_op.data.send_initial_metadata.count = metadata.count;
diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
index 99c890e4ee..7477da7619 100644
--- a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
@@ -40,8 +40,8 @@
@interface NSData (GRPCMetadata)
+ (instancetype)grpc_dataFromMetadataValue:(grpc_metadata *)metadata;
-// Fill a metadata object with the binary value in this NSData and the given key.
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key;
+// Fill a metadata object with the binary value in this NSData.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata;
@end
@implementation NSData (GRPCMetadata)
@@ -50,9 +50,7 @@
return [self dataWithBytes:metadata->value length:metadata->value_length];
}
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key {
- // TODO(jcanizales): Encode Unicode chars as ASCII.
- metadata->key = [key stringByAppendingString:@"-bin"].UTF8String;
+- (void)grpc_initMetadata:(grpc_metadata *)metadata {
metadata->value = self.bytes;
metadata->value_length = self.length;
}
@@ -63,8 +61,8 @@
@interface NSString (GRPCMetadata)
+ (instancetype)grpc_stringFromMetadataValue:(grpc_metadata *)metadata;
-// Fill a metadata object with the textual value in this NSString and the given key.
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key;
+// Fill a metadata object with the textual value in this NSString.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata;
@end
@implementation NSString (GRPCMetadata)
@@ -74,22 +72,8 @@
encoding:NSASCIIStringEncoding];
}
-- (void)grpc_initMetadata:(grpc_metadata *)metadata withKey:(NSString *)key {
- if ([key hasSuffix:@"-bin"]) {
- // Disallow this, as at best it will confuse the server. If the app really needs to send a
- // textual header with a name ending in "-bin", it can be done by removing the suffix and
- // encoding the NSString as a NSData object.
- //
- // Why raise an exception: In the most common case, the developer knows this won't happen in
- // their code, so the exception isn't triggered. In the rare cases when the developer can't
- // tell, it's easy enough to add a sanitizing filter before the header is set. There, the
- // developer can choose whether to drop such a header, or trim its name. Doing either ourselves,
- // silently, would be very unintuitive for the user.
- [NSException raise:NSInvalidArgumentException
- format:@"Metadata keys ending in '-bin' are reserved for NSData values."];
- }
- // TODO(jcanizales): Encode Unicode chars as ASCII.
- metadata->key = key.UTF8String;
+// Precondition: This object contains only ASCII characters.
+- (void)grpc_initMetadata:(grpc_metadata *)metadata {
metadata->value = self.UTF8String;
metadata->value_length = self.length;
}
@@ -105,8 +89,6 @@
+ (instancetype)grpc_dictionaryFromMetadata:(grpc_metadata *)entries count:(size_t)count {
NSMutableDictionary *metadata = [NSMutableDictionary dictionaryWithCapacity:count];
for (grpc_metadata *entry = entries; entry < entries + count; entry++) {
- // TODO(jcanizales): Verify in a C library test that it's converting header names to lower case
- // automatically.
NSString *name = [NSString stringWithCString:entry->key encoding:NSASCIIStringEncoding];
if (!name || metadata[name]) {
// Log if name is nil?
@@ -114,7 +96,6 @@
}
id value;
if ([name hasSuffix:@"-bin"]) {
- name = [name substringToIndex:name.length - 4];
value = [NSData grpc_dataFromMetadataValue:entry];
} else {
value = [NSString grpc_stringFromMetadataValue:entry];
@@ -124,19 +105,21 @@
return metadata;
}
+// Preconditions: All keys are ASCII strings. Keys ending in -bin have NSData values; the others
+// have NSString values.
- (grpc_metadata *)grpc_metadataArray {
grpc_metadata *metadata = gpr_malloc([self count] * sizeof(grpc_metadata));
- int i = 0;
- for (id key in self) {
+ grpc_metadata *current = metadata;
+ for (NSString* key in self) {
id value = self[key];
- grpc_metadata *current = &metadata[i];
- if ([value respondsToSelector:@selector(grpc_initMetadata:withKey:)]) {
- [value grpc_initMetadata:current withKey:key];
+ current->key = key.UTF8String;
+ if ([value respondsToSelector:@selector(grpc_initMetadata:)]) {
+ [value grpc_initMetadata:current];
} else {
[NSException raise:NSInvalidArgumentException
format:@"Metadata values must be NSString or NSData."];
}
- i += 1;
+ ++current;
}
return metadata;
}
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.h b/src/objective-c/GRPCClient/private/NSError+GRPC.h
index e712791271..f4729dc8a1 100644
--- a/src/objective-c/GRPCClient/private/NSError+GRPC.h
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.h
@@ -34,29 +34,6 @@
#import <Foundation/Foundation.h>
#include <grpc/grpc.h>
-// TODO(jcanizales): Make the domain string public.
-extern NSString *const kGRPCErrorDomain;
-
-// TODO(jcanizales): Make this public and document each code.
-typedef NS_ENUM(NSInteger, GRPCErrorCode) {
- GRPCErrorCodeCancelled = 1,
- GRPCErrorCodeUnknown = 2,
- GRPCErrorCodeInvalidArgument = 3,
- GRPCErrorCodeDeadlineExceeded = 4,
- GRPCErrorCodeNotFound = 5,
- GRPCErrorCodeAlreadyExists = 6,
- GRPCErrorCodePermissionDenied = 7,
- GRPCErrorCodeUnauthenticated = 16,
- GRPCErrorCodeResourceExhausted = 8,
- GRPCErrorCodeFailedPrecondition = 9,
- GRPCErrorCodeAborted = 10,
- GRPCErrorCodeOutOfRange = 11,
- GRPCErrorCodeUnimplemented = 12,
- GRPCErrorCodeInternal = 13,
- GRPCErrorCodeUnavailable = 14,
- GRPCErrorCodeDataLoss = 15
-};
-
@interface NSError (GRPC)
// Returns nil if the status code is OK. Otherwise, a NSError whose code is one of |GRPCErrorCode|
// and whose domain is |kGRPCErrorDomain|.