Skip to content

Commit

Permalink
Added more robust error handling (#87)
Browse files Browse the repository at this point in the history
* Added more robust error handling

* Added missing checks

* Added array error handling

* Added unit tests for new code
  • Loading branch information
mpetrenco authored Oct 26, 2020
1 parent 994dc7f commit f2a14e9
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 2 deletions.
12 changes: 11 additions & 1 deletion Examples/ObjectiveCExampleApp/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
PODS:
- CocoaDebug (1.3.3)
- Cucumberish (1.4.0)
- DeviceDNA (1.1.2)
- InAppSettingsKit (2.15)
- JudoKit-iOS (2.1.1):
Expand All @@ -11,6 +12,7 @@ PODS:

DEPENDENCIES:
- CocoaDebug
- Cucumberish (from `https://github.com/mpetrenco/Cucumberish.git`)
- InAppSettingsKit (= 2.15)
- JudoKit-iOS (from `../../`)

Expand All @@ -23,17 +25,25 @@ SPEC REPOS:
- ZappMerchantLib

EXTERNAL SOURCES:
Cucumberish:
:git: https://github.com/mpetrenco/Cucumberish.git
JudoKit-iOS:
:path: "../../"

CHECKOUT OPTIONS:
Cucumberish:
:commit: 6c09ec2fb600359f5bc7c4f4d6da279db723675c
:git: https://github.com/mpetrenco/Cucumberish.git

SPEC CHECKSUMS:
CocoaDebug: 610b36f29558ac74fa5653fbbbd1574fc7de54ed
Cucumberish: 6cbd0c1f50306b369acebfe7d9f514c9c287d26c
DeviceDNA: 3e72fd28d345a5aa6f218af4287cb46dc74b62cb
InAppSettingsKit: 4890a44f9df7a1742c632920f0ea939cbeb29ea2
JudoKit-iOS: eaf9974df969ee0cd18ae5a1daedf34ea00e331d
TrustKit: 073855e3adecd317417bda4ac9e9ac54a2e3b9f2
ZappMerchantLib: b14bc5814840426d351190309250347ca9b0983d

PODFILE CHECKSUM: 097c01342213a828220f23575b34beff9e4688d4
PODFILE CHECKSUM: 5c269b41354a7a58f7674d45095cde2f7fbee513

COCOAPODS: 1.9.3
154 changes: 154 additions & 0 deletions JudoKit_iOSTests/Extensions/JPError/JPErrorAdditionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,158 @@ class JPErrorAdditionsTests: XCTestCase {
let error = JPError.judoPBBAURLSchemeMissingError()
XCTAssertEqual(error.localizedDescription, "PBBA transactions require the deeplink scheme to be set.")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'message' field is present
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryContainsMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"message": "Page not found!"
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "Page not found!")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'message' field is not present
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryDoesNotContainsMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"sample": "Page not found!"
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "The request has failed with no underlying message.")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'details' field is present with a 'message' parameter
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryContainsDetailsWithMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"details": ["message": "Page not found!"]
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "Page not found!")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'details' field is present with no 'message' parameter
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryContainsDetailsWithNoMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"details": ["sample": "Page not found!"]
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "The request has failed with no underlying message.")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'details' field is present as the first element of an array dictionary with a 'message' parameter
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryContainsDetailsArrayWithMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"details": [
["message": "Page not found!"],
]
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "Page not found!")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'details' field is present as the first element of an array dictionary with no 'message' parameter
*
* THEN: the correct error should be generated
*/
func test_WhenJudoDictionaryContainsDetailsArrayWithNoMessage_ParseCorrectError() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"details": [
["sample": "Page not found!"],
]
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "The request has failed with no underlying message.")
}

/*
* GIVEN: the JPError is initialized from an NSDictionary
*
* WHEN: a 'code' field is present
*
* AND: a 'details' dictionary as well as a 'message' field are present
*
* THEN: the 'details' dictionary message should be prioritized
*/
func test_WhenJudoDictionaryContainsDetailsAndMessage_PrioritizeDetails() {

let sampleResponseFormat: [String: Any] = [
"code":404,
"message": "Another error message!",
"details": [
"message": "Page not found!",
]
]

let error = JPError.judoError(from: sampleResponseFormat)
XCTAssertEqual(error.code, 404)
XCTAssertEqual(error.localizedDescription, "Page not found!")
}
}
22 changes: 21 additions & 1 deletion Source/Extensions/JPError/JPError+Additions.m
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,27 @@ + (JPError *)judoUnsupportedCardNetwork:(JPCardNetworkType)network {
+ (JPError *)judoErrorFromDictionary:(NSDictionary *)dictionary {
NSString *defaultMessage = @"error_no_message_desc".localized;

NSString *parsedMessage = [dictionary valueForKey:@"message"];
NSString *parsedMessage;
NSObject *parsedDetails = [dictionary valueForKey:@"details"];

if ([parsedDetails isKindOfClass:NSArray.class]) {
NSArray *parsedArray = (NSArray *)parsedDetails;

if ([parsedArray.firstObject isKindOfClass:NSDictionary.class]) {
NSDictionary *parsedDictionary = (NSDictionary *)parsedArray.firstObject;
parsedMessage = [parsedDictionary valueForKey:@"message"];
}
}

if ([parsedDetails isKindOfClass:NSDictionary.class]) {
NSDictionary *parsedDictionary = (NSDictionary *)parsedDetails;
parsedMessage = [parsedDictionary valueForKey:@"message"];
}

if (parsedMessage == nil) {
parsedMessage = [dictionary valueForKey:@"message"];
}

NSString *message = parsedMessage == nil ? defaultMessage : parsedMessage;

return [self errorWithDescription:message
Expand Down

0 comments on commit f2a14e9

Please sign in to comment.