Skip to content

Parsing of events can throw an exception if ConferencingProvider name doesn't match any value from enum #265

@DanielNovak

Description

@DanielNovak

Parsing of calendar events will throw an exception if the conference provider name is different than the defined list in ConferencingProvider:

For example we have a user where the provider name is Hangouts.
The parser should either return null if it can't parse the provider or it should fall back to some "UNKNOWN" value.

Stacktrace:

"class": "com.squareup.moshi.JsonDataException",
14
"message": "Expected one of [Zoom Meeting, Google Meet, Microsoft Teams, WebEx, GoToMeeting, skypeForConsumer] but was Hangouts at path $.provider",
15
"stackTrace": "at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.fromJson(StandardJsonAdapters.java:296) at 
com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.fromJson(StandardJsonAdapters.java:264) at 
com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:41) at 
com.squareup.moshi.kotlin.reflect.KotlinJsonAdapter.fromJson(KotlinJsonAdapter.kt:86) at 
com.squareup.moshi.internal.NullSafeJsonAdapter.fromJson(NullSafeJsonAdapter.java:41) at 
com.squareup.moshi.JsonAdapter.fromJsonValue(JsonAdapter.java:126) at 
com.nylas.util.ConferencingAdapter.fromJson(ConferencingAdapter.kt:22) at 
java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at 
java.base/java.lang.reflect.Method.invoke(Method.java:580) at 
com.squareup.moshi.AdapterMethodsFactory$AdapterMethod.invoke(AdapterMethodsFactory.java:383) at

We had to override a lot of the NylasClient locally to override executeRequest and then to push a custom Moshi Adapter to fix it like this:

 class ConferencingProviderAdapter : JsonAdapter<ConferencingProvider>() {
        private val logger = LoggerFactory.getLogger(this::class.java)

        @FromJson
        override fun fromJson(reader: JsonReader): ConferencingProvider? {
            val value = reader.nextString()

            val foundEnum = ConferencingProvider.entries.find { getJsonName(it) == value }

            return if (foundEnum == null) {
                logger.warn("Unknown ConferencingProvider value: $value, returning null")
                null
            } else {
                foundEnum
            }

        }

        @ToJson
        override fun toJson(writer: JsonWriter, value: ConferencingProvider?) {
            writer.value(value?.name)
        }

        private fun getJsonName(enumValue: ConferencingProvider): String {
            return enumValue::class.java.getField(enumValue.name)
                .getAnnotation(Json::class.java)?.name ?: enumValue.name
        }
    }

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions