Description
Step 0: Are you in the right place?
- For issues or feature requests related to the code in this repository
file a GitHub issue.- If this is a feature request please use the Feature Request template.
- For general technical questions, post a question on StackOverflow
with thefirebase
tag. - For general (non-iOS) Firebase discussion, use the firebase-talk
google group. - For backend issues, console issues, and other non-SDK help that does not fall under one
of the above categories, reach out to
Firebase Support. - Once you've read this section and determined that your issue is appropriate for
this repository, please delete this section.
[REQUIRED] Step 1: Describe your environment
- Xcode version: 13.4
- Firebase SDK version: 9.1.0
- Installation method:
CocoaPods
(select one) - Firebase Component: Functions
- Target platform(s):
iOS
[REQUIRED] Step 2: Describe the problem
I'm forward-porting react-native-firebase to firebase-ios-sdk v9+ and I noticed a regression in custom error message behavior.
Prior to v9 here, if a function threw a custom HttpsError, the custom error details would be reflected in the error returned from the SDK, but with v9 all custom errors appear to be mapped to 'INTERNAL', which is the generic HTTP 500 response code mapping
Steps to reproduce:
Code up a simple test cloud function that will return an error if you supply it with nothing, or use ours:
const{ type, asError, inputData }=data;if(!Object.hasOwnProperty.call(SAMPLE_DATA,type)){thrownewfunctions.https.HttpsError('invalid-argument','Invalid test requested.');}
Call that cloud function, with no arguments so it will return the custom error:
it('errors return instance of HttpsError',asyncfunction(){constfunctionRunner=firebase.functions().httpsCallable('testFunctionDefaultRegion');try{awaitfunctionRunner({});returnPromise.reject(newError('Function did not reject with error.'));}catch(e){should.equal(e.details,null);e.code.should.equal('invalid-argument');e.message.should.equal('Invalid test requested.');}
Relevant Code:
...which goes to this Objective-C code:
NSURL *url = [NSURLURLWithString:customUrlOrRegion]; FIRFunctions *functions = (url && url.scheme && url.host) ? [FIRFunctions functionsForApp:firebaseApp customDomain:customUrlOrRegion] : [FIRFunctions functionsForApp:firebaseApp region:customUrlOrRegion]; if (host != nil) { [functions useEmulatorWithHost:host port:[port intValue]]; } FIRHTTPSCallable *callable = [functions HTTPSCallableWithName:name]; if (options[@"timeout"]) { callable.timeoutInterval = [options[@"timeout"] doubleValue]; } [callable callWithObject:[wrapper valueForKey:@"data"] completion:^(FIRHTTPSCallableResult *_Nullable result, NSError *_Nullable error) { if (error) { NSObject *details = [NSNullnull]; NSString *message = error.localizedDescription; NSMutableDictionary *userInfo = [NSMutableDictionarydictionary]; if ([error.domain isEqual:@"com.firebase.functions"]) { details = error.userInfo[@"details"]; if (details == nil) { details = [NSNullnull]; } } userInfo[@"code"] = [selfgetErrorCodeName:error]; userInfo[@"message"] = message; userInfo[@"details"] = details; [RNFBSharedUtils rejectPromiseWithUserInfo:reject userInfo:userInfo]; } else { resolve(@{@"data" : [result data]}); } }]; }
and just returns internal
instead of the expected invalid-argument
code with description from the function. firebase-android-sdk still returns the custom code/message
I threw a log message in to get the raw error from the SDK immediately after it falls into the if(error)
case:
NSLog(@"FIREBASE FUNCTIONS ERROR: %@", error);
which yields
2022-05-27 01:03:03.602 Df testing[54318:76b6d] FIREBASE FUNCTIONS ERROR: Error Domain=com.firebase.functions Code=13 "INTERNAL" UserInfo={NSLocalizedDescription=INTERNAL}
Looks like something about the Obj-C --> Swift port missed custom error handling somehow?