Custom exception with Guava Preconditions
Asked Answered
S

5

6

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.

Snappy answered 20/12, 2013 at 15:36 Comment(0)
S
5

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();
    }
}

}

Snappy answered 26/10, 2016 at 17:13 Comment(0)
B
7

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.

Bumblebee answered 20/12, 2013 at 15:39 Comment(0)
S
5

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();
    }
}

}

Snappy answered 26/10, 2016 at 17:13 Comment(0)
S
3

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:

Sweetheart answered 1/12, 2014 at 0:8 Comment(0)
L
3

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();
    }
}
Luhey answered 31/3, 2017 at 9:36 Comment(0)
G
1

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.

Guria answered 20/12, 2013 at 15:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.