2

I am trying to decode the error as follows, most of the error that I am handling in array format [String], but in few cases the error is not in array format, just a String.

If error comes in array format name comes as errors, but if it is string format then it comes as error. How could I handle this scenario?

How could I able to handle this scenario?

struct CustomError: Codable {
  let errors: [String]
}

private func errorDecoding(data : Data) {
 let decoder = JSONDecoder()
 do {
  let errorData = try decoder.decode(CustomError.self, from: data)
 } catch {
  // TODO
 }
}
1
  • This answer might be helpful. Commented Oct 11, 2020 at 17:34

1 Answer 1

5

You'd have to manually implement init(from:) and try decoding one type, failing that, decode another:

struct CustomError {
  let errors: [String]
}

extension CustomError: Decodable {
  enum CodingKeys: CodingKey { case errors, error }

  init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    do {
       self.errors = try container.decode([String].self, forKey: .errors) 
    } catch DecodingError.typeMismatch, 
            DecodingError.keyNotFound {
       let error = try container.decode(String.self, forKey: .error)
       self.errors = [error]
    }
  }
}

The decoding part is normal:

do {
   let error = try JSONDecoder().decode(CustomError.self, from: data)
} catch {
  // ..
}

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for quick answer. If error comes in array format name comes as errors, but if it is string format then it comes as error. How could I handle this scenario?
I would like to catch the error and throw it if there is any issues, I think do and catch is needed?
@NewDev init(from:) function just needs a throws at the end to pass the compile.
You are throwing away the error unnecessarily. There is no need to use try?. Just catch the typeMismatch DecodingError and decode your string do { self.errors = try container.decode([String].self, forKey: .errors) } catch DecodingError.typeMismatch { self.errors = try [container.decode(String.self, forKey: .error)] }
@LeoDabus, i think you'd also need to catch keyNotFound, but yeah - I can update the answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.