0

I have a Java class pojo in which I want the Object.toString() method to return a JSON representation of the object. The users of toString() want JSON only. This is my toString().

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

@Override
public String toString(){
    ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
    String json = null;
    try {
        json = ow.writeValueAsString(this);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    return json;
}

The problem is that the above code will swallow the exception and allow execution to continue. To avoid such problems, we can either throw exception or re-throw the exception as an unchecked exception as mentioned here Java - overriding Object's toString() method, but I have to throw exceptions.

But, toString() does not allow us to throw exceptions. So, we can only throw an unchecked exception. The above link's selected answer says that "throwing exceptions from toString() is a really bad idea". It suggests to return a error string instead which seems bad to me because we are really just swallowing the exception. The other suggestion is to throw IllegalStateExcception instead. Is this the ideal exception to throw in this situation or should we throw another one ? Thanks.

UPDATE : I corrected a mistake in my code. The toString() method does not take a parameter.

Erran Morad
  • 4,563
  • 10
  • 43
  • 72
  • 2
    `"But, toString() does not allow us to throw exceptions"` -- not true as this is not a classic `toString()` method as it takes a parameter, and so I see no problem with this method throwing whatever exception you desire. – Hovercraft Full Of Eels Nov 11 '19 at 19:02
  • @AndyTurner: better a checked exception, and declare the method as throwing this, no? – Hovercraft Full Of Eels Nov 11 '19 at 19:07
  • 1
    "The users of toString() want JSON only" that doesn't look right. Are you sure you understood your requirements correctly (and why does that `toString` method accept parameter)? Also should that representation be formatted in many lines? If yes what should be its indentation? – Pshemo Nov 11 '19 at 19:07
  • @Pshemo - The toString() method is just used for logging the expected response for an api. The pojo i talked about is a Java representation of that Json response. We don't use the toString() of the pojo for anything else. – Erran Morad Nov 11 '19 at 19:39
  • @HovercraftFullOfEels - Does the 2nd approach in this answer sound correct ? https://stackoverflow.com/a/42011744/3184475 – Erran Morad Nov 11 '19 at 19:41
  • @HovercraftFullOfEels - Sorry, I made a mistake while copying my code into this question. The toString() method is standard and does not take any argument. – Erran Morad Nov 11 '19 at 19:44
  • Please attempt to be more careful as our time on this site is all volunteer time, and no sense in our wasting our time chasing rabbits down the wrong hole. – Hovercraft Full Of Eels Nov 11 '19 at 21:36
  • @HovercraftFullOfEels - agree. sorry about that. If you downvoted, I request you to please undo it. thanks. – Erran Morad Nov 12 '19 at 00:18

1 Answers1

4

I would also advise against throwing an exception from toString. The method is often used for debugging purposes (whether its via System.out or with a debugger). Throwing excpetions just complicates things and makes everything harder.

Instead, I would suggest to add a toJSON method that throws either a JsonProcessingException or a (subclass of) RuntimeException, and implement toString such that it calls toJson, catches all exceptions and returns the error message in such cases.

Cephalopod
  • 14,632
  • 7
  • 51
  • 70
  • thanks. I wonder why we are delegating the json conversion to toJson() and then letting toString() catch all exceptions and return the error messages. Can't we do all that directly inside toString() - convert to json and if there is an exception, then return the error ? – Erran Morad Nov 11 '19 at 20:14
  • 1
    By keeping a separate toJSON method, you still have the option to do proper error handling if needed. You should always try to implement only one thing per method. In this case, toJSON converts to JSON, if possible(!); while toString always returns a String. – Cephalopod Nov 12 '19 at 08:51