1

I’m having trouble understanding and using the DecodingError.typeMismatch associated values in a catch clause.

I can use it fine without the associated values. I try decoding Type A in my do block and then catch the typeMismatch and try decoding Type B in the catch block.

How can I use the associated values to try catching a second typeMismatch, so that I can try decoding Type C in an additional catch block?

For example, if I catch DecodingError.typeMismatch(let type, _), can I use type in a where clause to try catching an additional typeMismatch error?

I’ve been playing around with this and the associated value ‘type’ that is returned is Double but that’s not what I’ve tried decoding. I don’t really understand what type is supposed to be.

Edit: Adding my existing code. My first two cases work perfectly, but after adding the second catch, Xcode warns me it won't ever be executed since I'm already catching that error. What I'd like to do is use the associated values of typeMismatch and a where clause, so that I can try each catch one at a time.

    enum FeatureGeometryCoordinates: Decodable {
        
        // cases
        case polygon([[CGPoint]])
        case multipolygon([[[CGPoint]]])
        case point(CGPoint)
        
        // init()
        init(from decoder: Decoder) throws {
            
            let container = try decoder.singleValueContainer()
            
            do {

                let polygonVal = try container.decode([[CGPoint]].self)
                self = .polygon(polygonVal)
            } catch DecodingError.typeMismatch {

                let multipolygonVal = try container.decode([[[CGPoint]]].self)
                self = .multipolygon(multipolygonVal)
            } catch DecodingError.typeMismatch {

                let pointVal = try container.decode(CGPoint.self)
                self = .point(pointVal)
            }
        }
    }
whaleshark
  • 65
  • 6
  • How would you expect to decode a type that there is no guarantee that conforms to Decodable? If you have do idea what type it might be better to decode it using JSONSerialization tools. – Leo Dabus Oct 16 '22 at 19:00
  • @LeoDabus I know it’s one of three types. I have an enum with an associated value for each type. It’s a GeoJSON geometry where it might be a point, polygon, or multipolygon. Maybe there are better ways to handle this than the do catch pattern? – whaleshark Oct 16 '22 at 19:03
  • Well just try one at a time. – Leo Dabus Oct 16 '22 at 19:06
  • This might help https://stackoverflow.com/a/71370811/2303865 – Leo Dabus Oct 16 '22 at 19:10
  • I added my enum and some additional explanation. @LeoDabus – whaleshark Oct 16 '22 at 19:23
  • You can't. You need to nest the catch. – Leo Dabus Oct 16 '22 at 19:30
  • @LeoDabus I think I can differentiate them using the where clause so that each catch would be distinct and circumvent this problem, but I don't know how to use the associated values of DecodingError.typeMismatch(let type, let context) where [conditional statement using type or context] – whaleshark Oct 16 '22 at 19:34
  • No need to use the associated values. Check my post below. – Leo Dabus Oct 16 '22 at 19:37

1 Answers1

0

Unfortunately you can't. You will need to nest the catch.

enum FeatureGeometryCoordinates: Decodable {
    case polygon([[CGPoint]])
    case multipolygon([[[CGPoint]]])
    case point(CGPoint)
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = try .polygon(container.decode([[CGPoint]].self))
        } catch DecodingError.typeMismatch {
            do {
                self = try .multipolygon(container.decode([[[CGPoint]]].self))
            } catch DecodingError.typeMismatch {
                self = try .point(container.decode(CGPoint.self))
            }
        }
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571