Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Functions/Backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,9 @@ exports.httpErrorTest = functions.https.onRequest((request, response) => {
// Send an http error with no body.
response.status(400).send();
});

exports.timeoutTest = functions.https.onRequest((request, response) => {
// Wait for longer than 500ms.
setTimeout(() => response.send({data: true}), 500);
});

1 change: 1 addition & 0 deletions Functions/Backend/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ FUNCTIONS_BIN="./node_modules/.bin/functions"
"${FUNCTIONS_BIN}" deploy unknownErrorTest --trigger-http
"${FUNCTIONS_BIN}" deploy explicitErrorTest --trigger-http
"${FUNCTIONS_BIN}" deploy httpErrorTest --trigger-http
"${FUNCTIONS_BIN}" deploy timeoutTest --trigger-http

# Wait for the user to tell us to stop the server.
echo "Functions emulator now running in ${TEMP_DIR}."
Expand Down
14 changes: 14 additions & 0 deletions Functions/Example/IntegrationTests/FIRIntegrationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,18 @@ - (void)testHttpError {
[self waitForExpectations:@[ expectation ] timeout:10];
}

- (void)testTimeout {
XCTestExpectation *expectation = [[XCTestExpectation alloc] init];
FIRHTTPSCallable *function = [_functions HTTPSCallableWithName:@"timeoutTest"];
function.timeoutInterval = 0.05;
[function callWithCompletion:^(FIRHTTPSCallableResult *_Nullable result, NSError *_Nullable error) {
XCTAssertNotNil(error);
XCTAssertEqual(FIRFunctionsErrorCodeDeadlineExceeded, error.code);
XCTAssertEqualObjects(@"DEADLINE EXCEEDED", error.userInfo[NSLocalizedDescriptionKey]);
XCTAssertNil(error.userInfo[FIRFunctionsErrorDetailsKey]);
[expectation fulfill];
}];
[self waitForExpectations:@[ expectation ] timeout:10];
}

@end
1 change: 1 addition & 0 deletions Functions/FirebaseFunctions/FIRFunctions+Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)callFunction:(NSString *)name
withObject:(nullable id)data
timeout:(NSTimeInterval)timeout
completion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
NSError *_Nullable error))completion;

Expand Down
15 changes: 13 additions & 2 deletions Functions/FirebaseFunctions/FIRFunctions.m
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ - (NSString *)URLWithName:(NSString *)name {

- (void)callFunction:(NSString *)name
withObject:(nullable id)data
timeout:(NSTimeInterval)timeout
completion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
NSError *_Nullable error))completion {
[_contextProvider getContext:^(FUNContext *_Nullable context, NSError *_Nullable error) {
Expand All @@ -168,16 +169,21 @@ - (void)callFunction:(NSString *)name
}
return;
}
return [self callFunction:name withObject:data context:context completion:completion];
return [self callFunction:name withObject:data timeout:timeout context:context completion:completion];
}];
}

- (void)callFunction:(NSString *)name
withObject:(nullable id)data
timeout:(NSTimeInterval)timeout
context:(FUNContext *)context
completion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
NSError *_Nullable error))completion {
GTMSessionFetcher *fetcher = [_fetcherService fetcherWithURLString:[self URLWithName:name]];
NSURL *url = [NSURL URLWithString:[self URLWithName:name]];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:timeout];
GTMSessionFetcher *fetcher = [_fetcherService fetcherWithRequest:request];

NSMutableDictionary *body = [NSMutableDictionary dictionary];
// Encode the data in the body.
Expand Down Expand Up @@ -225,6 +231,11 @@ - (void)callFunction:(NSString *)name
if ([error.domain isEqualToString:kGTMSessionFetcherStatusDomain]) {
error = FUNErrorForResponse(error.code, data, serializer);
}
if ([error.domain isEqualToString:NSURLErrorDomain]) {
if (error.code == NSURLErrorTimedOut) {
error = FUNErrorForCode(FIRFunctionsErrorCodeDeadlineExceeded);
}
}
} else {
// If there wasn't an HTTP error, see if there was an error in the body.
error = FUNErrorForResponse(200, data, serializer);
Expand Down
6 changes: 5 additions & 1 deletion Functions/FirebaseFunctions/FIRHTTPSCallable.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ - (instancetype)initWithFunctions:(FIRFunctions *)functions name:(NSString *)nam
}
_name = [name copy];
_functions = functions;
_timeoutInterval = 60.0;
}
return self;
}
Expand All @@ -63,7 +64,10 @@ - (void)callWithCompletion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
- (void)callWithObject:(nullable id)data
completion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
NSError *_Nullable error))completion {
[_functions callFunction:_name withObject:data completion:completion];
[_functions callFunction:_name
withObject:data
timeout:self.timeoutInterval
completion:completion];
}

@end
Expand Down
8 changes: 8 additions & 0 deletions Functions/FirebaseFunctions/FUNError.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@
// limitations under the License.

#import <Foundation/Foundation.h>
#import "FIRError.h"

@class FUNSerializer;

NS_ASSUME_NONNULL_BEGIN

/**
* Takes an error code and returns a corresponding NSError.
* @param code The eror code.
* @return The corresponding NSError.
*/
NSError *_Nullable FUNErrorForCode(FIRFunctionsErrorCode code);

/**
* Takes an HTTP status code and optional body and returns a corresponding NSError.
* If an explicit error is encoded in the JSON body, it will be used.
Expand Down
6 changes: 5 additions & 1 deletion Functions/FirebaseFunctions/FUNError.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// limitations under the License.

#import "FUNError.h"
#import "FIRError.h"

#import "FUNSerializer.h"

Expand Down Expand Up @@ -141,6 +140,11 @@ FIRFunctionsErrorCode FIRFunctionsErrorCodeForName(NSString *name) {
return @"UNKNOWN";
}

NSError *_Nullable FUNErrorForCode(FIRFunctionsErrorCode code) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : FUNDescriptionForErrorCode(code) };
return [NSError errorWithDomain:FIRFunctionsErrorDomain code:code userInfo:userInfo];
}

NSError *_Nullable FUNErrorForResponse(NSInteger status,
NSData *_Nullable body,
FUNSerializer *serializer) {
Expand Down
5 changes: 5 additions & 0 deletions Functions/FirebaseFunctions/Public/FIRHTTPSCallable.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ NS_SWIFT_NAME(HTTPSCallable)
NS_SWIFT_NAME(call(_:completion:));
// clang-format on

/**
* The timeout to use when calling the function. Defaults to 60 seconds.
*/
@property(nonatomic, assign) NSTimeInterval timeoutInterval;

@end

NS_ASSUME_NONNULL_END