美文网首页
和JSON处理相关的常见错误

和JSON处理相关的常见错误

作者: 醉看红尘这场梦 | 来源:发表于2020-04-26 11:25 被阅读0次

一直以来,我们都忽略了在编码和解码JSON时可能发生的各种错误。在了解了各种正常情况的处理方法之后,这一节,我们集中来看错误处理的问题。

处理不合法的JSON格式

第一个要处理的情况,是要解码的JSON格式不合法,这可能是多种原因造成的,例如服务端的程序有bug,或者网络传输问题等。为了演示,我们人为创建一个非法的JSON:

let response = """
{
    "1":{
        "title": "Episode 1"
    },
    "2": {
        "title": "Episode 2"
    },
    "3": {
        "title": "Episode 3"

}
"""

还是上一节中的内容,只不过,我们在最后故意去掉了一个}。然后直接调用上一节的全局decode

try decode(response: response, of: Episodes.self)

就会在控制台看到一个DecodingError.dataCorrupted异常,为了处理它,我们得修改一下这个decode函数:

func decode<T>(response: String, of: T.Type) throws -> T where T: Codable {
    let data = response.data(using: .utf8)!
    let decoder = JSONDecoder()

    do {
        let model = try decoder.decode(T.self, from: data)

        return model
    }
    catch DecodingError.typeMismatch(let type, let context) {
        dump(type)
        dump(context)
        exit(-1)
    }
}

这次,我们捕获了DecodingError.dataCorrupted异常,它有一个关联值,类型是DecodingError.Context,我们把这个值dump出来,就能看到下面的结果了:

▿ Swift.DecodingError.Context
  - codingPath: 0 elements
  - debugDescription: "The given data was not valid JSON."
  ▿ underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unexpected end of file while parsing object."

其中,debugDescription给出了错误信息的概述,而underlyingError则是一个Error?对象,包含了更具体的错误信息,这里,它提示我们Unexpected end of file while parsing object

处理不存在的key

第二种错误情况,是访问了不存在的key,例如,我们先定义一个CodingKey

enum DemoKey: String, CodingKey {
    case demo
}

接下来,在解码的时候,我们使用这个Demokey

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

    var v = [Episode]()
    for key in container.allKeys {
        let innerContainer = try container.nestedContainer(
            keyedBy: DemoKey.self, forKey: key)

        /// !!! Error
        let title = try innerContainer.decode(
            String.self, forKey: .demo)
        /// !!! Error

        let episode = Episode(id: Int(key.stringValue)!, title: title)
        v.append(episode)
    }

    self.episodes = v
}

在上面这个例子中,当我们在子容器中尝试读取key "demo"对应的值时,就会发生运行时错误。我们可以在decode全局函数中通过捕获keyNotFound出来key不存在的异常:

do {
    _ = try decoder.decode(Episodes.self, from: data)
}
catch DecodingError.keyNotFound(let codingPath, let context) {
    dump(codingPath)
    dump(context)
}

执行一下,就会看到它们的值了:

- Codable.DemoKey.demo
▿ Swift.DecodingError.Context
  - codingPath: 0 elements
  - debugDescription: "No value associated with key demo (\"demo\")."
  - underlyingError: nil

处理JSON值和model类型不匹配

最后一类错误,是JSON中包含的值和model中对应属性的类型不同。为了看到这个错误,我们把init方法改成这样:

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

        var v = [Episode]()
        for key in container.allKeys {
            let innerContainer = try container.nestedContainer(
                keyedBy: EpisodeInfo.self, forKey: key)

            let title = try innerContainer.decode(
                Int.self, forKey: .title)
        }

        self.episodes = v
    }

这次,我们在解码的时候,把title对应的类型,改成了Int,但JSON中包含的是String,因此重新执行就会发生异常。对此,我们可以通过捕获DecodingError.typeMismatch来处理:

do {
    _ = try decoder.decode(Episodes.self, from: data)
}
catch DecodingError.typeMismatch(let type, let context) {
    dump(type)
    dump(context)
}

这个异常也有两个关联值,分别表示了编码错误的类型,和我们熟悉的context对象,执行一下,就可以看到下面的结果了:

- Swift.Int #0
▿ Swift.DecodingError.Context
  ▿ codingPath: 1 element
    ▿ Codable.Episodes.EpisodeInfo
      - stringValue: "title"
  - debugDescription: "Expected to decode Int but found a string/data instead."
  - underlyingError: nil

以上,就是把JSON映射到Swift model时三种常见的错误处理。除了解码之外,当我们编码一个Swift model时,只有可能遇到一种错误,就是model属性的类型,无法编码到指定的容器中。大家可以自己了解下enum EncodingError,道理是一样的,我们就不重复了。

相关文章

  • 和JSON处理相关的常见错误

    一直以来,我们都忽略了在编码和解码JSON时可能发生的各种错误。在了解了各种正常情况的处理方法之后,这一节,我们集...

  • HarmonyOS安装调试

    1. HarmonyProfile.json 解析相关错误码问题描述:【常见解析相关错误码】[HARMONY_IN...

  • PHP基础学习之路(3)

    这一次学习php的错误处理和异常处理主要介绍常见的错误和异常 常见错误 1.拼写错误 PHP中的常量和变量都是区别...

  • SpringBoot定制错误的json数据时,处理结果显示mes

    错误描述:如图,在练习SpringBoot定制错误的json数据时,处理结果显示message和exception...

  • python异常处理

    程序的错误通常分为,语法错误,运行错误和逻辑错误 一个最常见的错误 python的异常 异常处理的语句 pytho...

  • 2019-06-17php版本变更5.6-7.0

    错误和异常处理相关的变更关于 在 PHP 7 中,很多致命错误以及可恢复的致命错误,都被转换为异常来处理了。 这些...

  • Python学习记录之:错误、调试和测试

    错误处理 常见的错误类型和继承关系看这里:https://docs.python.org/2/library/ex...

  • ios JSON解析常见错误

    1、 JSON数据带有转义字符 iOS现有Json解析框架+ ( id)JSONObjectWithData:o...

  • 十四、Error处理、泛型

    错误处理(异常处理) 错误类型 开发过程中常见的错误: 语法错误(编译报错) 逻辑错误 (偏离开发人员本意) 运行...

  • [Swift5.1] 15-错误处理

    错误处理也就是异常处理 错误类型 开发过程常见的错误 语法错误(编译报错) 逻辑错误 运行时错误(可能会导致闪退,...

网友评论

      本文标题:和JSON处理相关的常见错误

      本文链接:https://www.haomeiwen.com/subject/rznuehtx.html