3

i have a moshi custom json adapter for skip bad elements as follow:

class SkipBadElementsListAdapter(private val elementAdapter: JsonAdapter<Any?>) :
JsonAdapter<List<Any?>>() {
object Factory : JsonAdapter.Factory {
    override fun create(
        type: Type,
        annotations: Set<Annotation>,
        moshi: Moshi
    ): JsonAdapter<*>? {
        if (annotations.isNotEmpty() || Types.getRawType(type) != List::class.java) {
            return null
        }
        val elementType = Types.collectionElementType(type, List::class.java)
        val elementAdapter = moshi.adapter<Any?>(elementType)
        return SkipBadElementsListAdapter(elementAdapter).nullSafe()
    }
}

override fun fromJson(reader: JsonReader): List<Any?>? {

    val result = mutableListOf<Any?>()
    reader.beginArray()
    while (reader.hasNext()) {
        try {
            val peeked = reader.peekJson()
            result += elementAdapter.fromJson(peeked)
        } catch (ignored: JsonDataException) {
            Timber.tag("JsonParseError").d(ignored.toString())
        }
        reader.skipValue()
    }
    reader.endArray()
    return result

}

override fun toJson(writer: JsonWriter, value: List<Any?>?) {

    if (value == null) {
        throw NullPointerException("value was null! Wrap in .nullSafe() to write nullable values.")
    }
    writer.beginArray()
    for (i in value.indices) {
        elementAdapter.toJson(writer, value[i])
    }
    writer.endArray()
}

}

but after add this custom json adapter i receive a lot off fatal error in firebase:

Fatal Exception: java.lang.AssertionError
   at com.squareup.moshi.JsonUtf8Reader.<init>(JsonUtf8Reader.java:118)
   at com.squareup.moshi.JsonUtf8Reader.peekJson(JsonUtf8Reader.java:1076)
   at ir.part.app.signal.core.util.api.SkipBadElementsListAdapter.fromJson(SkipBadElementsListAdapter.java:30)
   at ir.part.app.signal.core.util.api.SkipBadElementsListAdapter.fromJson(SkipBadElementsListAdapter.java:7)
   at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:137)
   at ir.part.app.signal.core.model.SignalListResponseJsonAdapter.fromJson(SignalListResponseJsonAdapter.java:41)
   at ir.part.app.signal.core.model.SignalListResponseJsonAdapter.fromJson(SignalListResponseJsonAdapter.java:17)
   at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:137)
   at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:45)
   at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
   at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
   at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
   at com.google.firebase.perf.network.zzh.onResponse(zzh.java:22)
   at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
   at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
   at java.lang.Thread.run(Thread.java:776)

i look in moshi lib code and guess problem occur in "sourcePeek.require":

    JsonUtf8Reader(JsonUtf8Reader copyFrom) {
    ...
    // Make sure our buffer has as many bytes as the source's buffer. This is necessary because
    // JsonUtf8Reader assumes any data it has peeked (like the peekedNumberLength) are buffered.
    try {
      sourcePeek.require(copyFrom.buffer.size());
    } catch (IOException e) {
      throw new AssertionError();
    }
}

what is wrong by my custom moshi adapter?! i want skip bad element from json receive from server in a list of data and show correct items.

h.kelidari
  • 800
  • 1
  • 11
  • 20

1 Answers1

1

The skipping adapter doesn’t know how much to skip. You want it to skip to the end of the current list element, bit the crash may have left the JsonReader partially through a complex object.

Work around by passing peekJson() to the delegate adapter and always skipping regardless of whether there was an exception.or not.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • i'm using adapter from : https://stackoverflow.com/a/54190660/2667925. my problem is such as https://stackoverflow.com/questions/54145519/moshi-adapter-to-skip-bad-objects-in-the-listt. but when i'm using this solution cause error! – h.kelidari Dec 30 '19 at 11:29