jsonserializ .data(withJSONObject:)在什么情况下抛出可捕获的错误?

时间:2021-08-12 22:12:09

JSONSerialization.data(withJSONObject:options:) (aka dataWithJSONObject in Swift 2) is declared throws. However, passing invalid objects causes a crash, not a catchable error:

jsonserializ .data(withJSONObject:options:)(即Swift 2中的dataWithJSONObject)被声明为抛出。但是,传递无效的对象会导致崩溃,而不是可跟踪的错误:

do  {
    // Crash
    try JSONSerialization.data(
        withJSONObject: NSObject(),
        options: [])
    }
catch
    {
    // Never reached
    print("Caught error:", error)
    }

Why is that method declared “throws,” then? Under what circumstances does it throw an exception?

为什么那个方法被声明为“抛出”?在什么情况下会抛出异常?

Not knowing what causes an error to be thrown makes it hard to know how to handle the error, and makes it impossible to write tests that verify that handling.

不知道是什么原因导致抛出错误,这使得我们很难知道如何处理错误,也不可能编写验证该处理的测试。

1 个解决方案

#1


6  

Turns out it’s the same situation as this question: you can create a Swift string that contains invalid unicode (what?!), and that causes an exception.

事实证明,这与这个问题是相同的情况:您可以创建一个包含无效unicode(什么?!)的Swift字符串,这会导致异常。

let bogusStr = String(
    bytes: [0xD8, 0x00] as [UInt8],
    encoding: String.Encoding.utf16BigEndian)!

do  {
    let rawBody = try JSONSerialization.data(
        withJSONObject: ["foo": bogusStr], options: [])
    }
catch
    {
    // Exception lands us here
    print("Caught error:", error)
    }

Why does the example code in the original question crash, then, instead of also throwing an error?

为什么原始问题中的示例代码会崩溃,而不是抛出错误?

Replying to a bug report, Apple informed me that you should call JSONSerialization.isValidJSONObject(_:) before data(withJSONObject:) if you don’t know for sure that the object is encodable, failing to do that is a misuse of the API, and that’s why they decided it should crash instead of throwing something catchable.

在回复一个bug报告时,苹果通知我,如果您不确定该对象是可编码的,那么应该在数据(withJSONObject:)之前调用jsonaliz . isvalidjsonobject(_:),如果您不确定该对象是可编码的,那么失败就是对API的误用,因此他们决定它应该崩溃,而不是抛出可捕获的东西。

#1


6  

Turns out it’s the same situation as this question: you can create a Swift string that contains invalid unicode (what?!), and that causes an exception.

事实证明,这与这个问题是相同的情况:您可以创建一个包含无效unicode(什么?!)的Swift字符串,这会导致异常。

let bogusStr = String(
    bytes: [0xD8, 0x00] as [UInt8],
    encoding: String.Encoding.utf16BigEndian)!

do  {
    let rawBody = try JSONSerialization.data(
        withJSONObject: ["foo": bogusStr], options: [])
    }
catch
    {
    // Exception lands us here
    print("Caught error:", error)
    }

Why does the example code in the original question crash, then, instead of also throwing an error?

为什么原始问题中的示例代码会崩溃,而不是抛出错误?

Replying to a bug report, Apple informed me that you should call JSONSerialization.isValidJSONObject(_:) before data(withJSONObject:) if you don’t know for sure that the object is encodable, failing to do that is a misuse of the API, and that’s why they decided it should crash instead of throwing something catchable.

在回复一个bug报告时,苹果通知我,如果您不确定该对象是可编码的,那么应该在数据(withJSONObject:)之前调用jsonaliz . isvalidjsonobject(_:),如果您不确定该对象是可编码的,那么失败就是对API的误用,因此他们决定它应该崩溃,而不是抛出可捕获的东西。