Skip to content

Commit

Permalink
Provide PMHTTPStatusCodeErrorKey user info key for more error types
Browse files Browse the repository at this point in the history
Fixes #59.
  • Loading branch information
lilyball committed Apr 24, 2019
1 parent ab9d2c3 commit 7b55118
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ work by you shall be dual licensed as above, without any additional terms or con
* Add computed properties on `HTTPManagerError` for convenient access to the associated values (e.g. `.response`, `.body`, etc).
* Add computed property `HTTPManagerError.statusCode` that returns the failing status code for the error, or `nil` for `.unexpectedContentType` ([#60][]).
* Add Obj-C function `PMHTTPErrorGetStatusCode()` that returns the failing status code for the error, or `nil` for `PMHTTPErrorUnexpectedContentType` or for non-PMHTTP errors ([#60][]).
* Provide `PMHTTPStatusCodeErrorKey` user info key for more error types ([#59][]).

[#59]: https://github.com/postmates/PMHTTP/issues/59 "PMHTTPStatusCodeErrorKey should be used for unauthorized and unexpectedNoContent · Issue #59 · postmates/PMHTTP"
[#60]: https://github.com/postmates/PMHTTP/issues/60 "HTTPManagerError should have .statusCode property · Issue #60 · postmates/PMHTTP"
[#62]: https://github.com/postmates/PMHTTP/issues/62 "Unknown Hint Identifier for Image MIME Types · Issue #62 · postmates/PMHTTP"

Expand Down
4 changes: 3 additions & 1 deletion Sources/ObjectiveC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ extension HTTPManagerError: CustomNSError {
var userInfo: [String: Any] = [
NSLocalizedDescriptionKey: auth?.localizedDescription?(for: self) ?? "401 Unauthorized HTTP response",
PMHTTPURLResponseErrorKey: response,
PMHTTPStatusCodeErrorKey: 401,
PMHTTPBodyDataErrorKey: body
]
userInfo[PMHTTPAuthErrorKey] = auth
Expand All @@ -273,7 +274,8 @@ extension HTTPManagerError: CustomNSError {
case let .unexpectedNoContent(response):
return [
NSLocalizedDescriptionKey: "HTTP response returned 204 No Content when an entity was expected",
PMHTTPURLResponseErrorKey: response]
PMHTTPURLResponseErrorKey: response,
PMHTTPStatusCodeErrorKey: 204]
case let .unexpectedRedirect(statusCode, location, response, body):
let statusString = HTTPURLResponse.localizedString(forStatusCode: statusCode)
var userInfo: [String: Any] = [
Expand Down
3 changes: 3 additions & 0 deletions Sources/PMHTTPError.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ BOOL PMHTTPErrorIsFailedResponse(NSError * _Nullable error, NSInteger statusCode
return [errorStatusCode isKindOfClass:[NSNumber class]] ? errorStatusCode : nil;
}
case PMHTTPErrorUnauthorized:
// NB: Ignore PMHTTPStatusCodeErrorKey and just hardcode the status here, because there's only one valid code.
// This protects us from hand-crafted `NSError`s that are missing the key.
return @401;
case PMHTTPErrorUnexpectedContentType:
return nil;
case PMHTTPErrorUnexpectedNoContent:
// NB: See above regarding hardcoding the status code.
return @204;
}
return nil;
Expand Down
21 changes: 21 additions & 0 deletions Tests/PMHTTPErrorTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@ - (void)testPMHTTPErrorGetStatusCode {
XCTAssertEqualObjects(PMHTTPErrorGetStatusCode([ObjCTestSupport createUnexpectedNoContentErrorWith:response]), @204, @"unexpectedNoContent");
XCTAssertEqualObjects(PMHTTPErrorGetStatusCode([ObjCTestSupport createUnexpectedRedirectErrorWithStatusCode:301 location:nil response:response body:[NSData data]]), @301, @"unexpectedRedirect code 301");
XCTAssertEqualObjects(PMHTTPErrorGetStatusCode([ObjCTestSupport createUnexpectedRedirectErrorWithStatusCode:304 location:nil response:response body:[NSData data]]), @304, @"unexpectedRedirect code 304");

// Ensure we're not relying on PMHTTPStatusCodeErrorKey for the error types that don't need it
XCTAssertEqualObjects(PMHTTPErrorGetStatusCode(errorWithStatusCode([ObjCTestSupport createUnauthorizedErrorWith:nil response:response body:[NSData data] bodyJson:nil], 500)), @401, @"unauthorized with modified status code userInfo key");
XCTAssertEqualObjects(PMHTTPErrorGetStatusCode(errorWithStatusCode([ObjCTestSupport createUnexpectedNoContentErrorWith:response], 500)), @204, @"unexpectedNoContent");
}

- (void)testPMHTTPStatusCodeErrorKey {
// Ensure we provide PMHTTPStatusCodeErrorKey for all errors that PMHTTPErrorGetStatusCode returns a value for
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://example.com"] statusCode:419 HTTPVersion:nil headerFields:nil];

XCTAssertEqualObjects([ObjCTestSupport createFailedResponseErrorWithStatusCode:404 response:response body:[NSData data] bodyJson:nil].userInfo[PMHTTPStatusCodeErrorKey], @404, @"failedResponse code 404");
XCTAssertEqualObjects([ObjCTestSupport createUnauthorizedErrorWith:nil response:response body:[NSData data] bodyJson:nil].userInfo[PMHTTPStatusCodeErrorKey], @401, @"unauthorized");
XCTAssertNil([ObjCTestSupport createUnexpectedContentTypeErrorWithContentType:@"text/plain" response:response body:[NSData data]].userInfo[PMHTTPStatusCodeErrorKey], @"unexpectedContentType");
XCTAssertEqualObjects([ObjCTestSupport createUnexpectedNoContentErrorWith:response].userInfo[PMHTTPStatusCodeErrorKey], @204, @"unexpectedNoContent");
XCTAssertEqualObjects([ObjCTestSupport createUnexpectedRedirectErrorWithStatusCode:304 location:nil response:response body:[NSData data]].userInfo[PMHTTPStatusCodeErrorKey], @304, @"unexpectedRedirect");
}

static NSError * _Nonnull errorWithStatusCode(NSError * _Nonnull error, NSInteger statusCode) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
userInfo[PMHTTPStatusCodeErrorKey] = @(statusCode);
return [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
}

@end

0 comments on commit 7b55118

Please sign in to comment.