EMZETT.
Login

Error Codes

In short: Numeric or textual identifiers that identify a type of error — e.g. the exit code of a Java program (System.exit(1)) or custom error codes in an exception.

In more detail: Java itself primarily works with typed exceptions instead of pure error codes as in C — but a custom exception class with a field for an error code often combines both approaches, e.g. when connecting to an external API with numeric codes.

In Depth

// Custom exception with an attached error code for an external API integration
class ApiException extends RuntimeException {
    private final int errorCode;
 
    public ApiException(String message, int errorCode) {
        super(message);
        this.errorCode = errorCode;
    }
 
    public int getErrorCode() {
        return errorCode;
    }
}
 
try {
    // ... API call that fails with HTTP status code 404
    throw new ApiException("Resource not found", 404);
} catch (ApiException e) {
    if (e.getErrorCode() == 404) {
        System.out.println("Not found - using default value");
    } else {
        throw e; // unknown code - rethrow instead of swallowing
    }
}
 
System.exit(1); // process exit code 1 signals an error to the calling shell script

The process exit code (0 to 255, 0 conventionally means “success”) is especially relevant for command-line tools or scripts embedded in a larger pipeline — a calling shell script or a CI pipeline checks this code to decide whether the next step should run. System.exit() should be used sparingly: it terminates the JVM immediately and can bypass finally blocks and proper resource cleanup in the process — in normal application classes, an error should almost always be handled as a thrown exception, System.exit() remains reserved for the very topmost entry point (main).

Error codes vs. exception hierarchies

Languages like C or Go traditionally rely more heavily on error codes as return values instead of exceptions — the caller has to manually check the return value of EVERY call, or an error is silently ignored. Java’s exception mechanism reverses this: an uncaught exception automatically propagates upward and, in the worst case, terminates the program with a stack trace instead of simply being overlooked. The downside of exceptions is the somewhat higher runtime cost when actually thrown (stack trace creation) — in performance-critical code that very frequently handles expectable “errors” (e.g. when parsing large amounts of data with some invalid lines), a return-value pattern with optional values (Optional<T>) is therefore sometimes deliberately used instead of exceptions.

HTTP status codes as the best-known example

The pattern shown above (exception with an attached numeric code) is most commonly encountered in practice with HTTP clients: 4xx codes (client errors, e.g. 404 Not Found, 401 Unauthorized) and 5xx codes (server errors, e.g. 500 Internal Server Error) are often translated into a typed exception hierarchy, so that calling code can respond specifically to certain error types without having to interpret the raw numeric code itself every time.

See also: Exceptions, Errors