Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to define error codes/strings in Java?

Tags:

java

enums

People also ask

How do you write error codes in Java?

Both the error code and error string will be sent to the client accessing the web service. For example, when a SQLException occurs, I might want to do the following: // Example: errorCode = 1, // errorString = "There was a problem accessing the database." throw new SomeWebServiceException(errorCode, errorString);

How are error codes defined?

The error code is a specific number that identifies what the error is to the system. It also can be helpful in finding a resolution to the problem. If you're getting an error code, search for the error code number and where you're getting the error to find a resolution.

How do I use enum error codes?

Enum constructors can never be invoked in the code, they are always called automatically when an enum is initialized. You can't create instance of Enum using new operator, it should have a private constructor and is normally initialized as: ErrorCodes error = ErrorCodes.

What does string error mean?

As its name implies, the unclosed string literal error refers to a string literal which has not been closed. More specifically, this means that the Java compiler has failed to interpret a string literal due to being unable to locate the double quote expected to close i.e., mark the end of it.


Well there's certainly a better implementation of the enum solution (which is generally quite nice):

public enum Error {
  DATABASE(0, "A database error has occurred."),
  DUPLICATE_USER(1, "This user already exists.");

  private final int code;
  private final String description;

  private Error(int code, String description) {
    this.code = code;
    this.description = description;
  }

  public String getDescription() {
     return description;
  }

  public int getCode() {
     return code;
  }

  @Override
  public String toString() {
    return code + ": " + description;
  }
}

You may want to override toString() to just return the description instead - not sure. Anyway, the main point is that you don't need to override separately for each error code. Also note that I've explicitly specified the code instead of using the ordinal value - this makes it easier to change the order and add/remove errors later.

Don't forget that this isn't internationalised at all - but unless your web service client sends you a locale description, you can't easily internationalise it yourself anyway. At least they'll have the error code to use for i18n at the client side...


As far as I am concerned, I prefer to externalize the error messages in a properties files. This will be really helpful in case of internationalization of your application (one properties file per language). It is also easier to modify an error message, and it won't need any re-compilation of the Java sources.

On my projects, generally I have an interface that contains errors codes (String or integer, it doesn't care much), which contains the key in the properties files for this error:

public interface ErrorCodes {
    String DATABASE_ERROR = "DATABASE_ERROR";
    String DUPLICATE_USER = "DUPLICATE_USER";
    ...
}

in the properties file:

DATABASE_ERROR=An error occurred in the database.
DUPLICATE_USER=The user already exists.
...

Another problem with your solution is the maintenability: you have only 2 errors, and already 12 lines of code. So imagine your Enumeration file when you will have hundreds of errors to manage!


Overloading toString() seems a bit icky -- that seems a bit of a stretch of toString()'s normal use.

What about:

public enum Errors {
  DATABASE(1, "A database error has occured."),
  DUPLICATE_USER(5007, "This user already exists.");
  //... add more cases here ...

  private final int id;
  private final String message;

  Errors(int id, String message) {
     this.id = id;
     this.message = message;
  }

  public int getId() { return id; }
  public String getMessage() { return message; }
}

seems a lot cleaner to me... and less verbose.


At my last job I went a little deeper in the enum version:

public enum Messages {
    @Error
    @Text("You can''t put a {0} in a {1}")
    XYZ00001_CONTAINMENT_NOT_ALLOWED,
    ...
}

@Error, @Info, @Warning are retained in the class file and are available at runtime. (We had a couple of other annotations to help describe message delivery as well)

@Text is a compile-time annotation.

I wrote an annotation processor for this that did the following:

  • Verify that there are no duplicate message numbers (the part before the first underscore)
  • Syntax-check the message text
  • Generate a messages.properties file that contains the text, keyed by the enum value.

I wrote a few utility routines that helped log errors, wrap them as exceptions (if desired) and so forth.

I'm trying to get them to let me open-source it... -- Scott


I'd recommend that you take a look at java.util.ResourceBundle. You should care about I18N, but it's worth it even if you don't. Externalizing the messages is a very good idea. I've found that it was useful to be able to give a spreadsheet to business folks that allowed them to put in the exact language they wanted to see. We wrote an Ant task to generate the .properties files at compile time. It makes I18N trivial.

If you're also using Spring, so much the better. Their MessageSource class is useful for these sorts of things.