Handling runtime type mismatch exceptions gracefully — GSON
By: Asheesh Sharma
Tags: Android App Development, Android, Programming, AndroidDev, Json

We all have faced a situation where a single key data type mismatch sometimes breaks the whole application. This post is partially inclined towards devs who have been using gson for parsing and want to make their life easier by handling such exceptions gracefully over a blunt crash on their application.

The problem with gson is whenever a datatype of the key is not matched it throws a fatal exception(JsonSyntaxException) and breaks the process of parsing the remaining response.

Now we have two ways to handle it gracefully

- Handle the exception at view/screen level and show a no content view screen.[Something went wrong, please try again in a while]

To achieve this — Just add a try catch at repository or the base network layer and throw errorView on that particular page.[Con — Block the user from using the app completely]

- Handle the exception at the parsing level and ignore the key which is causing that error and let the rest of the parsing goes smoothly.

I will be sharing an insight into how can we implement the second solution.

Here is a small tweak you can do to the gson instance creation which you can use across app wherever you have a requirement of parsing gson.

// Gson instance creation

private static Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().registerTypeAdapterFactory(new InvalidTypeParserFactory()).create();

// InvalidTypeParserFactory

public class InvalidTypeParserFactory implements TypeAdapterFactory {

@Override

public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {

final TypeAdapter<T> adapter = gson.getDelegateAdapter(this, type);

return new TypeAdapter<T>() {

@Override

public void write(JsonWriter out, T value) throws IOException {

adapter.write(out, value);

}



@Override

public T read(JsonReader in) throws IOException {

try {

return adapter.read(in);

} catch (Throwable e) {

ZCrashLogger.logAndPrintException(e);

consumeAll(in);

return null;

}



}



private void consumeAll(JsonReader in) throws IOException {

if (in.hasNext()) {

JsonToken peek = in.peek();

if (peek == JsonToken.STRING) {

in.nextString();

} else if (peek == JsonToken.BEGIN_ARRAY) {

in.beginArray();

consumeAll(in);

in.endArray();

} else if (peek == JsonToken.BEGIN_OBJECT) {

in.beginObject();

consumeAll(in);

in.endObject();

} else if (peek == JsonToken.END_ARRAY) {

in.endArray();

} else if (peek == JsonToken.END_OBJECT) {

in.endObject();

} else if (peek == JsonToken.NUMBER) {

in.nextString();

} else if (peek == JsonToken.BOOLEAN) {

in.nextBoolean();

} else if (peek == JsonToken.NAME) {

in.nextName();

consumeAll(in);

} else if (peek == JsonToken.NULL) {

in.nextNull();

}

}

}

};

}

}

Disadvantage — Sometimes UX wont be predictable but the call you need to take basis on the frequency of the occurrence and how critical the logic is of your page.

voilà! That should help you handle type mismatch exceptions in in GSON parsing.

Note —

If you want to use specific exception instead of throwable, you can use JsonSyntaxException to avoid catching all other exceptions.

Feel free to connect if you want to discuss anything cool, always up for discussions.

Link - https://www.linkedin.com/in/asheesh-sharma-codeyourstack/