elvishew/xLog

Parse JSON error

Closed this issue · 15 comments

I init your xLog in the application onCreate() with XLog.init(LogLevel.ALL);, but when I run my project it fail to print json string, only give me this error com.elvishew.xlog.formatter.FormatException: Parse JSON error. It's works well using android.util.Log to print the json string, don't know anything wrong, any help?

@chowaikong It is mostly because the string you tried to print is not a JSON, can you check if what you print is realy a JSON string?

But why can Gson parses the JSON string?

@chowaikong Is it possile you paste the JSON string here, or send to elvis@fossil.com, so I can take a further look?

Please check your email.

@chowaikong In my side, I call XLog.json(the_json_you_sent_me), and the formatted JSON is successfully printed, so I don't know how you got the error.

Can you print the full error stack of FormatException to see what the exception actually is?

Also, you can take a look at the DefaultJsonFormatter, the formatting code is very simple.

  try {
      if (json.startsWith("{")) {
        JSONObject jsonObject = new JSONObject(json);
        formattedString = jsonObject.toString(JSON_INDENT);
      } else if (json.startsWith("[")) {
        JSONArray jsonArray = new JSONArray(json);
        formattedString = jsonArray.toString(JSON_INDENT);
      } else {
        throw new FormatException("JSON should start with { or [, but found " + json);
      }
    } catch (Exception e) {
      throw new FormatException("Parse JSON error. JSON string:" + json, e);
    }

This code snippet seems hardly to be wrong.

Sorry for the delay, m.elvishew.xlog.formatter.FormatException: Parse JSON error. is the only exception I encounter, but I can tell you some detail of my project's build environment, I'm using OkHttp for the network job, with HttpLoggingInterceptor to print the network log, hope it helps.

@chowaikong I understand, I need the root cause exception of the FormatException, can you help to pointing it out using below codes:

try {
  XLog.json(Your JSON string);
} catch (Exception e) {
  android.util.Log.i("ERROR", "The exception is: ", e);
}

And use logcat or Android Studio to see the printed ERROR log?

For example, I use below codes to test:

try {
  XLog.json("{abc}");
} catch (Exception e) {
  android.util.Log.i("ERROR", "The exception is: ", e);
}

and got below ERROR log

I/ERROR   (  957): The exception is:
I/ERROR   (  957): com.elvishew.xlog.formatter.FormatException: Parse JSON error. JSON string:{abc}
I/ERROR   (  957): 	at com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter.format(DefaultJsonFormatter.java:48)
I/ERROR   (  957): 	at com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter.format(DefaultJsonFormatter.java:27)
I/ERROR   (  957): 	at com.elvishew.xlog.Logger.json(Logger.java:388)
I/ERROR   (  957): 	at com.elvishew.xlog.XLog.json(XLog.java:648)
I/ERROR   (  957): 	at com.elvishew.xlogsample.MainActivity$5.onClick(MainActivity.java:122)
I/ERROR   (  957): 	at android.view.View.performClick(View.java:4764)
I/ERROR   (  957): 	at android.view.View$PerformClick.run(View.java:19833)
I/ERROR   (  957): 	at android.os.Handler.handleCallback(Handler.java:739)
I/ERROR   (  957): 	at android.os.Handler.dispatchMessage(Handler.java:95)
I/ERROR   (  957): 	at android.os.Looper.loop(Looper.java:135)
I/ERROR   (  957): 	at android.app.ActivityThread.main(ActivityThread.java:5292)
I/ERROR   (  957): 	at java.lang.reflect.Method.invoke(Native Method)
I/ERROR   (  957): 	at java.lang.reflect.Method.invoke(Method.java:372)
I/ERROR   (  957): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
I/ERROR   (  957): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
I/ERROR   (  957): Caused by: org.json.JSONException: Expected ':' after abc at character 5 of {abc}
I/ERROR   (  957): 	at org.json.JSONTokener.syntaxError(JSONTokener.java:450)
I/ERROR   (  957): 	at org.json.JSONTokener.readObject(JSONTokener.java:379)
I/ERROR   (  957): 	at org.json.JSONTokener.nextValue(JSONTokener.java:100)
I/ERROR   (  957): 	at org.json.JSONObject.<init>(JSONObject.java:156)
I/ERROR   (  957): 	at org.json.JSONObject.<init>(JSONObject.java:173)
I/ERROR   (  957): 	at com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter.format(DefaultJsonFormatter.java:39)
I/ERROR   (  957): 	... 14 more

So I can figure out the root exception is

I/ERROR   (  957): Caused by: org.json.JSONException: Expected ':' after abc at character 5 of {abc}
I/ERROR   (  957): 	at org.json.JSONTokener.syntaxError(JSONTokener.java:450)
...

Thank you

I have try the code below:

try {
    XLog.json(json);
    } catch (Exception e) {
    Log.e("HttpLoggingInterceptor", e.toString());
}

And still the same exception, no further information.

@chowaikong
android.util.Log.i("ERROR", "The exception is: ", e); is different from Log.e("HttpLoggingInterceptor", e.toString());, the latter one will not print the root cause.

Can you try Log.e("HttpLoggingInterceptor", "The exception is: ", e); instead?

Right, now the exception maybe meet your requirement.

Caused by: com.elvishew.xlog.formatter.FormatException: JSON should start with { or [, but found <-- END HTTP (9015-byte body)
                                                                       at com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter.format(DefaultJsonFormatter.java:45)
                                                                       at com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter.format(DefaultJsonFormatter.java:27) 
                                                                       at com.elvishew.xlog.Logger.json(Logger.java:382) 
                                                                       at com.elvishew.xlog.XLog.json(XLog.java:630) 

@chowaikong
This error com.elvishew.xlog.formatter.FormatException: JSON should start with { or [, but found is not the same with that one com.elvishew.xlog.formatter.FormatException: Parse JSON error you mentioned in the very beginning, I think they are two different exceptions.

From the exception found <-- END HTTP (9015-byte body) you pasted, I wonder if your JSON string contains some comments(like "<--")? Since JSON string should not contain any comment, so the exception thrown.

<-- END HTTP (9015-byte body) is the ending of a http request, XLog is printing every lines of the response content according to the logcat.

As a comparison, I try KLog too, this lib prints json string just normally fine. And I think the json string printing method is quite similar between two libraries.

@chowaikong I check KLog's JSON parser, it is the same as xLog's, the only difference between these two is, KLog catch the JSONException(mostly because the message is not a JSON) and leave the message not formatted, but xLog will throw an FormatException if the message is not a JSON when you call XLog.json.

I notice you may using the okhttp with HttpLoggingInterceptor and try to implement your own logger, the logger will automatically print many messages during requesting. But except the response data, all the other messages are not a JSON, so you can not just call XLog.json to print all of them.

If you are still using xLog, and want to format the JSON response data, try below codes when printing the okhttp log

try {
  XLog.json(message)
} catch (Exception e) {
  XLog.d(message)
}

Hope this can help you.

OK, thanks.