Home > Mobile >  Square Moshi casts Int to String if field type is wrong in response
Square Moshi casts Int to String if field type is wrong in response

Time:03-24

I'm trying to parse a JSON error body with structure

{
    "code": 1,
    "message": "Some error message"
}

While writing tests for scenario where message is sent as Int, I expect the deserialization to fail. However, Moshi converts the Int type to String. Is this behaviour expected?

Here's a failing test for the same:

    @Test
    fun `network error with wrong types should not be parsed`() {
        val errorResponseWithNoCode = """
        {
          "message": 123
        }
        """.trimIndent()

        val result = NetworkErrorParser.parse(errorResponseWithWrongMessageType)

        assertThat(result)
            .isEqualTo(null)
    }

The NetworkErrorParser is pretty simple:

object NetworkErrorParser {

    private val networkErrorAdapter by lazy {
        Moshi.Builder().build().adapter(NetworkError::class.java)
    }

    /**
     * Parses given string to [NetworkError].
     *
     * If JSON can't be parsed or is malformed, returns `null`.
     * The caller is supposed to handle the error accordingly in such an event.
     */
    fun parse(json: String): NetworkError? {
        return try {
            networkErrorAdapter.fromJson(json)
        } catch (e: JsonDataException) {
            null
        } catch (e: JsonEncodingException) {
            null
        }
    }
}

CodePudding user response:

This behavior is expected. Because JSON numbers have precision limitations Moshi allows you to assign numeric values to string properties and string values to numeric properties.

For example, you might decide to quote values like "9007199254740993" to defend against floating point precision loss.

  • Related