Skip to content

Commit 416e8d7

Browse files
Add failure reason to messaging NSError (#5511)
1 parent aeb837b commit 416e8d7

10 files changed

+132
-114
lines changed

FirebaseMessaging/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# unreleased
2+
- [changed] Updated NSError with a failure reason to give more details on the error.
3+
14
# 2020-04 -- v4.4.0
25
- [changed] Changed the location of source under FirebaseMessaging folder to fit the current repository organization.
36

FirebaseMessaging/Sources/FIRMessaging.m

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -578,14 +578,13 @@ - (NSString *)FCMToken {
578578
- (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID
579579
completion:(nonnull FIRMessagingFCMTokenFetchCompletion)completion {
580580
if (!senderID.length) {
581-
FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch,
582-
@"Sender ID not supplied. It is required for a token fetch, "
583-
@"to identify the sender.");
581+
NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid "
582+
@"Sender ID is required to fetch an FCM token";
583+
FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch, @"%@",
584+
description);
584585
if (completion) {
585-
NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid "
586-
@"Sender ID is required to fetch an FCM token";
587-
NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest
588-
userInfo:@{NSLocalizedDescriptionKey : description}];
586+
NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest
587+
failureReason:description];
589588
completion(nil, error);
590589
}
591590
return;
@@ -610,13 +609,13 @@ - (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID
610609
- (void)deleteFCMTokenForSenderID:(nonnull NSString *)senderID
611610
completion:(nonnull FIRMessagingDeleteFCMTokenCompletion)completion {
612611
if (!senderID.length) {
613-
FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete,
614-
@"Sender ID not supplied. It is required to delete an FCM token.");
612+
NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A "
613+
@"valid Sender ID is required to delete an FCM token";
614+
FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete, @"%@",
615+
description);
615616
if (completion) {
616-
NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A "
617-
@"valid Sender ID is required to delete an FCM token";
618-
NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest
619-
userInfo:@{NSLocalizedDescriptionKey : description}];
617+
NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest
618+
failureReason:description];
620619
completion(error);
621620
}
622621
return;
@@ -786,10 +785,12 @@ - (void)subscribeToTopic:(NSString *)topic
786785
[strongSelf.pubsub subscribeToTopic:normalizeTopic handler:completion];
787786
return;
788787
}
789-
FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009,
790-
@"Cannot parse topic name %@. Will not subscribe.", topic);
788+
NSString *failureReason =
789+
[NSString stringWithFormat:@"Cannot parse topic name: '%@'. Will not subscribe.", topic];
790+
FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009, @"%@", failureReason);
791791
if (completion) {
792-
completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]);
792+
completion([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
793+
failureReason:failureReason]);
793794
}
794795
}];
795796
}
@@ -824,10 +825,12 @@ - (void)unsubscribeFromTopic:(NSString *)topic
824825
[strongSelf.pubsub unsubscribeFromTopic:normalizeTopic handler:completion];
825826
return;
826827
}
827-
FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011,
828-
@"Cannot parse topic name %@. Will not unsubscribe.", topic);
828+
NSString *failureReason =
829+
[NSString stringWithFormat:@"Cannot parse topic name: '%@'. Will not unsubscribe.", topic];
830+
FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011, @"%@", failureReason);
829831
if (completion) {
830-
completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]);
832+
completion([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
833+
failureReason:failureReason]);
831834
}
832835
}];
833836
}

FirebaseMessaging/Sources/FIRMessagingClient.m

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,11 @@ - (void)updateSubscriptionWithToken:(NSString *)token
195195
shouldDelete:shouldDelete
196196
handler:completion];
197197
} else {
198-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRegistrar000,
199-
@"Device check in error, no auth credentials found");
200-
NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeMissingDeviceID];
198+
NSString *failureReason = @"Device ID and checkin info is not found. Will not proceed with "
199+
@"subscription/unsubscription.";
200+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRegistrar000, @"%@", failureReason);
201+
NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeMissingDeviceID
202+
failureReason:failureReason];
201203
handler(error);
202204
}
203205
}
@@ -267,10 +269,9 @@ - (void)retryConnectionImmediately:(BOOL)immediately {
267269
- (void)connectWithHandler:(FIRMessagingConnectCompletionHandler)handler {
268270
if (self.isConnected) {
269271
NSError *error =
270-
[NSError fcm_errorWithCode:kFIRMessagingErrorCodeAlreadyConnected
271-
userInfo:@{
272-
NSLocalizedFailureReasonErrorKey : @"FIRMessaging is already connected",
273-
}];
272+
[NSError messagingErrorWithCode:kFIRMessagingErrorCodeAlreadyConnected
273+
failureReason:
274+
@"FIRMessaging is already connected. Will not try to connect again."];
274275
handler(error);
275276
return;
276277
}
@@ -290,12 +291,13 @@ - (void)connect {
290291
self.stayConnected = YES;
291292
if (![[FIRInstanceID instanceID] tryToLoadValidCheckinInfo]) {
292293
// Checkin info is not available. This may be due to the checkin still being fetched.
294+
NSString *failureReason = @"Failed to connect to MCS. No deviceID and secret found.";
293295
if (self.connectHandler) {
294-
NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeMissingDeviceID];
296+
NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeMissingDeviceID
297+
failureReason:failureReason];
295298
self.connectHandler(error);
296299
}
297-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient009,
298-
@"Failed to connect to MCS. No deviceID and secret found.");
300+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient009, @"%@", failureReason);
299301
// Return for now. If checkin is, in fact, retrieved, the
300302
// |kFIRMessagingCheckinFetchedNotification| will be fired.
301303
return;
@@ -492,9 +494,8 @@ - (void)scheduleConnectRetry {
492494
// disconnect before issuing a callback
493495
[self disconnectWithTryToConnectLater:YES];
494496
NSError *error =
495-
[NSError errorWithDomain:@"No internet available, cannot connect to FIRMessaging"
496-
code:kFIRMessagingErrorCodeNetwork
497-
userInfo:nil];
497+
[NSError messagingErrorWithCode:kFIRMessagingErrorCodeNetwork
498+
failureReason:@"No internet available, cannot connect to FIRMessaging"];
498499
if (handler) {
499500
handler(error);
500501
self.connectHandler = nil;

FirebaseMessaging/Sources/FIRMessagingDataMessageManager.m

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ - (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage {
274274
}
275275

276276
if (![to length]) {
277-
[self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorMissingTo];
277+
[self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorCodeMissingTo];
278278
return;
279279
}
280280
[stanza setTo:to];
@@ -288,7 +288,9 @@ - (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage {
288288

289289
int size = [self addData:dataMessage[KFIRMessagingSendMessageAppData] toStanza:stanza];
290290
if (size > kMaxAppDataSizeDefault) {
291-
[self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorSizeExceeded];
291+
[self willSendDataMessageFail:stanza
292+
withMessageId:msgId
293+
error:kFIRMessagingErrorCodeSizeExceeded];
292294
return;
293295
}
294296

@@ -299,7 +301,7 @@ - (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage {
299301
if (!success) {
300302
[self willSendDataMessageFail:stanza
301303
withMessageId:msgId
302-
error:kFIRMessagingErrorSave];
304+
error:kFIRMessagingErrorCodeSave];
303305
return;
304306
}
305307
[self willSendDataMessageSuccess:stanza withMessageId:msgId];
@@ -403,11 +405,12 @@ - (void)willSendDataMessageSuccess:(GtalkDataMessageStanza *)stanza
403405
*/
404406
- (void)willSendDataMessageFail:(GtalkDataMessageStanza *)stanza
405407
withMessageId:(NSString *)messageId
406-
error:(FIRMessagingInternalErrorCode)errorCode {
407-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager011,
408-
@"Send message fail: %@ error: %lu", messageId, (unsigned long)errorCode);
408+
error:(FIRMessagingErrorCode)errorCode {
409+
NSString *failureReason = [NSString
410+
stringWithFormat:@"Send message fail: %@ error: %lu", messageId, (unsigned long)errorCode];
411+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager011, @"%@", failureReason);
409412

410-
NSError *error = [NSError errorWithFCMErrorCode:errorCode];
413+
NSError *error = [NSError messagingErrorWithCode:errorCode failureReason:failureReason];
411414
if ([self.delegate respondsToSelector:@selector(willSendDataMessageWithID:error:)]) {
412415
[self.delegate willSendDataMessageWithID:messageId error:error];
413416
}
@@ -459,7 +462,7 @@ - (BOOL)handleExpirationForDataMessage:(GtalkDataMessageStanza *)message {
459462
if (now > message.sent + message.ttl) {
460463
[self willSendDataMessageFail:message
461464
withMessageId:message.id_p
462-
error:kFIRMessagingErrorServiceNotAvailable];
465+
error:kFIRMessagingErrorCodeServiceNotAvailable];
463466
return NO;
464467
}
465468
return YES;

FirebaseMessaging/Sources/FIRMessagingPubSub.m

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ - (void)subscribeWithToken:(NSString *)token
6161
options:(NSDictionary *)options
6262
handler:(FIRMessagingTopicOperationCompletion)handler {
6363
if (!self.client) {
64-
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]);
64+
handler([NSError
65+
messagingErrorWithCode:kFIRMessagingErrorCodePubSubClientNotSetup
66+
failureReason:@"Firebase Messaging Client does not exist. Firebase Messaging was "
67+
@"not setup property and subscription failed."]);
6568
return;
6669
}
6770

@@ -73,9 +76,11 @@ - (void)subscribeWithToken:(NSString *)token
7376
}
7477

7578
if (![[self class] isValidTopicWithPrefix:topic]) {
76-
FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub000,
77-
@"Invalid FIRMessaging Pubsub topic %@", topic);
78-
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubInvalidTopic]);
79+
NSString *failureReason =
80+
[NSString stringWithFormat:@"Invalid subscription topic :'%@'", topic];
81+
FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub000, @"%@", failureReason);
82+
handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
83+
failureReason:failureReason]);
7984
return;
8085
}
8186

@@ -102,7 +107,10 @@ - (void)unsubscribeWithToken:(NSString *)token
102107
options:(NSDictionary *)options
103108
handler:(FIRMessagingTopicOperationCompletion)handler {
104109
if (!self.client) {
105-
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]);
110+
handler([NSError
111+
messagingErrorWithCode:kFIRMessagingErrorCodePubSubClientNotSetup
112+
failureReason:@"Firebase Messaging Client does not exist. Firebase Messaging was "
113+
@"not setup property and subscription failed."]);
106114
return;
107115
}
108116
token = [token copy];
@@ -112,9 +120,11 @@ - (void)unsubscribeWithToken:(NSString *)token
112120
}
113121

114122
if (![[self class] isValidTopicWithPrefix:topic]) {
115-
FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub002,
116-
@"Invalid FIRMessaging Pubsub topic %@", topic);
117-
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubInvalidTopic]);
123+
NSString *failureReason =
124+
[NSString stringWithFormat:@"Invalid topic name : '%@' for unsubscription.", topic];
125+
FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub002, @"%@", failureReason);
126+
handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
127+
failureReason:failureReason]);
118128
return;
119129
}
120130
if (![self verifyPubSubOptions:options]) {

FirebaseMessaging/Sources/FIRMessagingTopicOperation.m

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,10 @@ - (void)setFinished:(BOOL)finished {
120120

121121
- (void)start {
122122
if (self.isCancelled) {
123-
NSError *error =
124-
[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled];
123+
NSError *error = [NSError
124+
messagingErrorWithCode:kFIRMessagingErrorCodePubSubOperationIsCancelled
125+
failureReason:
126+
@"Failed to start the pubsub service as the topic operation is cancelled."];
125127
[self finishWithError:error];
126128
return;
127129
}
@@ -148,7 +150,8 @@ - (void)finishWithError:(NSError *)error {
148150
- (void)cancel {
149151
[super cancel];
150152
[self.dataTask cancel];
151-
NSError *error = [NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubOperationIsCancelled];
153+
NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodePubSubOperationIsCancelled
154+
failureReason:@"The topic operation is cancelled."];
152155
[self finishWithError:error];
153156
}
154157

@@ -210,16 +213,21 @@ - (void)performSubscriptionChange {
210213
}
211214
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
212215
if (response.length == 0) {
213-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOperationEmptyResponse,
214-
@"Invalid registration response - zero length.");
215-
[self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]];
216+
NSString *failureReason = @"Invalid registration response - zero length.";
217+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOperationEmptyResponse, @"%@",
218+
failureReason);
219+
[self finishWithError:[NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown
220+
failureReason:failureReason]];
216221
return;
217222
}
218223
NSArray *parts = [response componentsSeparatedByString:@"="];
219224
if (![parts[0] isEqualToString:@"token"] || parts.count <= 1) {
220-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002,
221-
@"Invalid registration response %@", response);
222-
[self finishWithError:[NSError errorWithFCMErrorCode:kFIRMessagingErrorCodeUnknown]];
225+
NSString *failureReason = [NSString
226+
stringWithFormat:@"Invalid registration response :'%@'. It is missing 'token' field.",
227+
response];
228+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002, @"%@", failureReason);
229+
[self finishWithError:[NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown
230+
failureReason:failureReason]];
223231
return;
224232
}
225233
[self finishWithError:nil];

FirebaseMessaging/Sources/NSError+FIRMessaging.h

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,54 +16,44 @@
1616

1717
#import <Foundation/Foundation.h>
1818

19+
#import <FirebaseMessaging/FIRMessaging.h>
20+
21+
NS_ASSUME_NONNULL_BEGIN
22+
1923
FOUNDATION_EXPORT NSString *const kFIRMessagingDomain;
2024

21-
typedef NS_ENUM(NSUInteger, FIRMessagingInternalErrorCode) {
22-
// Unknown error.
25+
// FIRMessaging Internal Error Code
26+
typedef NS_ENUM(NSUInteger, FIRMessagingErrorCode) {
2327
kFIRMessagingErrorCodeUnknown = 0,
2428

25-
// HTTP related errors.
26-
kFIRMessagingErrorCodeAuthentication = 1,
27-
kFIRMessagingErrorCodeNoAccess = 2,
28-
kFIRMessagingErrorCodeTimeout = 3,
2929
kFIRMessagingErrorCodeNetwork = 4,
3030

31-
// Another operation is in progress.
32-
kFIRMessagingErrorCodeOperationInProgress = 5,
33-
34-
// Failed to perform device check in.
35-
kFIRMessagingErrorCodeRegistrarFailedToCheckIn = 6,
36-
3731
kFIRMessagingErrorCodeInvalidRequest = 7,
3832

33+
kFIRMessagingErrorCodeInvalidTopicName = 8,
34+
3935
// FIRMessaging generic errors
4036
kFIRMessagingErrorCodeMissingDeviceID = 501,
4137

42-
// upstream send errors
43-
kFIRMessagingErrorServiceNotAvailable = 1001,
44-
kFIRMessagingErrorInvalidParameters = 1002,
45-
kFIRMessagingErrorMissingTo = 1003,
46-
kFIRMessagingErrorSave = 1004,
47-
kFIRMessagingErrorSizeExceeded = 1005,
48-
// Future Send Errors
38+
// Upstream send errors
39+
kFIRMessagingErrorCodeServiceNotAvailable = 1001,
40+
kFIRMessagingErrorCodeMissingTo = 1003,
41+
kFIRMessagingErrorCodeSave = 1004,
42+
kFIRMessagingErrorCodeSizeExceeded = 1005,
4943

50-
// MCS errors
5144
// Already connected with MCS
5245
kFIRMessagingErrorCodeAlreadyConnected = 2001,
5346

5447
// PubSub errors
55-
kFIRMessagingErrorCodePubSubAlreadySubscribed = 3001,
56-
kFIRMessagingErrorCodePubSubAlreadyUnsubscribed = 3002,
57-
kFIRMessagingErrorCodePubSubInvalidTopic = 3003,
58-
kFIRMessagingErrorCodePubSubFIRMessagingNotSetup = 3004,
48+
kFIRMessagingErrorCodePubSubClientNotSetup = 3004,
5949
kFIRMessagingErrorCodePubSubOperationIsCancelled = 3005,
6050
};
6151

6252
@interface NSError (FIRMessaging)
6353

64-
@property(nonatomic, readonly) FIRMessagingInternalErrorCode fcmErrorCode;
65-
66-
+ (NSError *)errorWithFCMErrorCode:(FIRMessagingInternalErrorCode)fcmErrorCode;
67-
+ (NSError *)fcm_errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo;
54+
+ (NSError *)messagingErrorWithCode:(FIRMessagingErrorCode)fcmErrorCode
55+
failureReason:(NSString *)failureReason;
6856

6957
@end
58+
59+
NS_ASSUME_NONNULL_END

FirebaseMessaging/Sources/NSError+FIRMessaging.m

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,11 @@
2020

2121
@implementation NSError (FIRMessaging)
2222

23-
- (FIRMessagingInternalErrorCode)fcmErrorCode {
24-
return (FIRMessagingInternalErrorCode)self.code;
25-
}
26-
27-
+ (NSError *)errorWithFCMErrorCode:(FIRMessagingInternalErrorCode)fcmErrorCode {
28-
return [NSError errorWithDomain:kFIRMessagingDomain code:fcmErrorCode userInfo:nil];
29-
}
30-
31-
+ (NSError *)fcm_errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo {
32-
return [NSError errorWithDomain:kFIRMessagingDomain code:code userInfo:userInfo];
23+
+ (NSError *)messagingErrorWithCode:(FIRMessagingErrorCode)errorCode
24+
failureReason:(NSString *)failureReason {
25+
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
26+
userInfo[NSLocalizedFailureReasonErrorKey] = failureReason;
27+
return [NSError errorWithDomain:kFIRMessagingDomain code:errorCode userInfo:userInfo];
3328
}
3429

3530
@end

0 commit comments

Comments
 (0)