Custom exception with Guava Preconditions

8.9k views Asked by At

It's very simple question, I often use com.google.common.base.Preconditions in my projects to validate arguments and parameters, for example:

Preconditions.checkNotNull(parameter, "message");
Preconditions.checkArgument(parameter > 0, "message");

this code may produce IllegalArgumentException or NPE. But very often I need throw own exception. How can I do it by this library? Or maybe you can advise another one? thank you in advance!

UPDATE: I understand, that I can to create own simple utility class, but I'm interested to find ready-made solutions. Please, let me know, if somebody know it's possible.

5

There are 5 answers

0
maxi On BEST ANSWER

That's the solution I finally came to. It does exactly what I wanted. Might be useful to anybody:

import java.lang.reflect.InvocationTargetException;

// IMPORTANT: parameter exClass must have at least no args constructor and constructor with String param
public class Precondition {

public static <T extends Exception> void checkArgument(boolean expression, Class<T> exClass) throws T {
    checkArgument(expression, exClass, null);
}

public static <T extends Exception> void checkArgument(boolean expression, Class<T> exClass, String errorMessage, Object... args) throws T {
    if (!expression) {
        generateException(exClass, errorMessage, args);
    }
}

public static <T extends Exception> void checkNotNull(Object reference, Class<T> exClass) throws T {
    checkNotNull(reference, exClass, null);
}

public static <T extends Exception> void checkNotNull(Object reference, Class<T> exClass, String errorMessage, Object... args) throws T {
    if (reference == null) {
        generateException(exClass, errorMessage, args);
    }
}

private static <T extends Exception> void generateException(Class<T> exClass, String errorMessage, Object... args) throws T {
    try {
        if (errorMessage == null) {
            throw exClass.newInstance();
        } else {
            throw exClass.getDeclaredConstructor(String.class, Object[].class).newInstance(errorMessage, args);
        }
    } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
        e.printStackTrace();
    }
}

}

0
keyoxy On

You can use valid4j with hamcrest-matchers instead (found on Maven Central as org.valid4j:valid4j)

For input validation throwing custom exceptions:

import static org.valid4j.Validation.*;

validate(argument, isValid(), otherwiseThrowing(InvalidException.class));

For preconditions and postconditions (i.e. assertions):

import static org.valid4j.Assertive.*;

require(argument, notNullValue());
...
ensure(result, isValid());

Links:

0
Jon Skeet On

If you want to throw your own exception, just create your own class with similar methods to the ones in Preconditions. Each of those methods is extremely simple - adding some sort of "plug-in" ability to allow the exception class to be specified would really be overkill compared with writing your own.

You could always use the source of Preconditions as a starting point.

0
Tim B On

The Exception types are hard coded into the Preconditions class. You will need to implement your own exception and your own checking function. You could always do it in a static class of your own similar to how Preconditions works.

0
Przemek Nowak On

You could always make something like that for you own (I don't know why the guys from guava did not add it yet):

public static void check(final boolean expression, RuntimeException exceptionToThrow) {
    if (!expression) {
        throw checkNotNull(exceptionToThrow);
    }
}

public static void check(final boolean expression, Supplier<? extends RuntimeException> exceptionToThrowSupplier) {
    if (!expression) {
        throw checkNotNull(exceptionToThrowSupplier).get();
    }
}