Home > Enterprise >  One url but different response on failure
One url but different response on failure

Time:01-19

First Response on success:

{
    "url": "demo.web.link",
    "id": "345345dgfgdfg34534545",
    "firstName": "Apple",
    "lastName": "iOS",
    "email": "[email protected]",
    "phone": ""
} 

when post data is incorrect at that time getting this response:

{
    "message": "The given data was invalid.",
    "errors": {
        "code": [
            "The provided code does not exist."
        ]
    }
}

I am using this struct:

struct AuthenticateResponse: Decodable {
    let url, id, firstName, lastName: String?
    let email, message, phone: String?
    let errors: Errors?
}
// MARK: - Errors
struct Errors: Decodable {
    let code: [String]?
}

My struct is working well for success but not working for failure. I am wondering what i am doing wrong.

Getting this error when i am providing incorrect data:

Error#####: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around line 1, column 0." UserInfo={NSDebugDescription=Invalid value around line 1, column 0., NSJSONSerializationErrorIndex=0})))

success response:

    "RESPONSE JSON"
username Response: AuthenticateResponse(url: nil, id: nil, firstName: nil, lastName: nil, email: nil, message: nil, phone: nil, status: Optional("available"), errors: nil)

CodePudding user response:

The code as posted does correctly parse the json when passed to a JSONDecoder so there could be something about the context it's used in that's causing the issue.


However, the current model requires all the fields to be optional. This can be annoying in other parts of the app where it'll need to check for the presence of every value to show it in the UI.

It could be changed to be two separate types to remove the need for the optional fields. Then it can be wrapped as two cases in a response type they tries to decode as success, and it that fails it tries to parse as failure and returns the values.

enum AuthenticateResponse: Decodable {
    struct Success: Decodable {
        let url, id, firstName, lastName: String
        let email, phone: String
    }

    struct Failure: Decodable {
        struct Errors: Decodable {
            let code: [String]
        }
        
        let message: String
        let errors: Errors
    }
    
    case success(Success)
    case failure(Failure)
    
    init(from decoder: Decoder) throws {
        do {
            let success = try Success(from: decoder)
            self = .success(success)
        } catch {
            let failure = try Failure(from: decoder)
            self = .failure(failure)
        }
    }
}

CodePudding user response:

It's working when you insert incorrect data at that point need to set your header by force to

request.setValue("application/json", forHTTPHeaderField: "Accept")

Before i was using :

if path.httpMethod == .get {
    request.setValue("application/json", forHTTPHeaderField: "Accept")
}
  •  Tags:  
  • Related