Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Null Pointers from JsonReader

I am using JsonReader to fetch lots of data from a website and saving to a db. Incidentally, whenever the reader doesnt find a value for an object item, it fails and stops executing.

This is the error i have;

System.err﹕ java.lang.IllegalStateException: Expected a string but was NULL at line 1 column 359337 path $[19].date

Even if the specified value is not available, it seems all objects loaded before the error was encountered are lost too and are not saved to the db. Is there a way to handle these errors and keep the objects that had been loaded so far? I have set JsonReader as lenient.

This is the part of the method that parses the data:

private Post read(JsonReader reader) throws Exception {
            reader.beginObject();

            while (reader.hasNext()) {
                String name = reader.nextName();

                switch (name) {
                    case TITLE:
                        mTitle = new StringBuilder();
                        mTitle.append(reader.nextString());
                        break;
                    case AUTHOR:
                        if (reader.hasNext()) {
                            JsonToken peek = reader.peek();

                            if (peek == JsonToken.NULL) {
                                reader.skipValue();
                            } else {
                                reader.beginObject();

                                while (reader.hasNext()) {
                                    String enclosedName = reader.nextName();

                                    switch (enclosedName) {
                                        case NAME:
                                            mAuthor = new StringBuilder();
                                            mAuthor.append(reader.nextString());
                                            break;
                                        case AVATAR:
                                            mAvatar = new StringBuilder();
                                            mAvatar.append(reader.nextString());
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    }
                                }

                                reader.endObject();
                            }
                        }
                        break;
                    case CONTENT:
                        mDescription = new StringBuilder();
                        mDescription.append(reader.nextString());
                        break;
                    case URL:
                        mEntryLink = new StringBuilder();
                        mEntryLink.append(reader.nextString());
                        break;
                    case DATE:
                        mDateStringBuilder = new StringBuilder();
                        mDateStringBuilder.append(reader.nextString());
                        break;
                    case GUID:
                        mGuid = new StringBuilder();
                        mGuid.append(reader.nextString());
                        break;
                    case FEATURED_IMAGE:
                        if (reader.hasNext()) {
                            JsonToken look = reader.peek();

                            if (look == JsonToken.NULL) {
                                reader.skipValue();
                            } else {
                                mFeaturedImage = new StringBuilder();
                                reader.beginObject();

                                while (reader.hasNext()) {
                                    String itemToLookFor = reader.nextName();

                                    switch (itemToLookFor) {
                                        case SOURCE:
                                            mFeaturedImage.append(reader.nextString());
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    }
                                }

                                reader.endObject();
                            }
                        }
                        break;
                    case TERMS:
                        if (reader.hasNext()) {
                            JsonToken check = reader.peek();

                            if (check == JsonToken.NULL) {
                                reader.skipValue();
                            } else {
                                reader.beginObject();

                                while (reader.hasNext()) {
                                    String stuff = reader.nextName();

                                    switch (stuff) {
                                        case CATEGORIES:
                                            reader.beginArray();

                                            itemCategory = new StringBuilder();

                                            while (reader.hasNext()) {
                                                reader.beginObject();

                                                while (reader.hasNext()) {
                                                    String item = reader.nextName();

                                                    switch (item) {
                                                        case NAME:
                                                            itemCategory.append(reader.nextString()).append(",");
                                                            break;
                                                        default:
                                                            reader.skipValue();
                                                            break;
                                                    }
                                                }

                                                reader.endObject();
                                            }
                                            reader.endArray();
                                            break;
                                        case TAGS:
                                            reader.beginArray();

                                            itemTags = new StringBuilder();

                                            while (reader.hasNext()) {
                                                reader.beginObject();

                                                while (reader.hasNext()) {
                                                    String item = reader.nextName();

                                                    switch (item) {
                                                        case NAME:
                                                            itemTags.append(reader.nextString()).append(",");
                                                            break;
                                                        default:
                                                            reader.skipValue();
                                                            break;
                                                    }
                                                }

                                                reader.endObject();
                                            }
                                            reader.endArray();
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    }
                                }

                                reader.endObject();
                            }
                        }
                        break;
                    default:
                        reader.skipValue();
                        break;
                }
            }

            reader.endObject();

            return new Post(mAuthor.toString(), mAvatar.toString(), mDateStringBuilder.toString(), mTitle.toString(), mEntryLink.toString(), mDescription.toString(), mGuid.toString(), mFeaturedImage.toString(), itemTags.toString(), itemCategory.toString());
        }
like image 634
Alex Kombo Avatar asked Feb 09 '23 12:02

Alex Kombo


1 Answers

I thought may be you weren't checking for NULL elements, that seems to be the case.

At one point you use:

JsonToken check = reader.peek();

if (check == JsonToken.NULL) {

That is correct. However, in other places you simply get the String:

mDescription.append(reader.nextString());

In all places you are getting a String, you need to check whether there is actually an unexpected type (such as NULL). In cases like this, you need to apply appropriate error containment code.

Incidentally, you really don't need to be creating all of those StringBuilders. Since you are only putting one String into it after each initialization. You would save a lot of time by simply using a String. If you intend to write all the contents to a StringBuilder for each type, then you need to initialize them before you start looping.

like image 86
Knossos Avatar answered Feb 22 '23 12:02

Knossos