Java - Avoid pattern duplication - java

Java
In my server code, for each method I will have to do the following
#Path("...")
public Response function(...) {
try {
result = do some work to get result
log the result
return result
} catch (Exception e) {
log error
return error
}
}
I will have to duplicate this pattern everywhere and only changing the do some work to get result part for new endpoint.
Is there a way that I can do to reduce this is duplication?
P.S. do some work to get result can be very something like getting a Json file, or accessing multiple database and calculate the result, and need to be in try-catch block.

You can create a function that looks like this:
public static <T> T doTheThing(Supplier<T> supp, Supplier<T> errorSupp) {
try {
T result = supp.get();
//log the result
return result;
} catch (Exception e) {
//log error
return errorSupp.get();
}
}
Then you can pass suppliers for a) the actual work and b) the potential error to this function.

Related

Proper way to get error message and code from exception

I have a simple try catch method that returns an exception as String
public class Program {
try {
someFunction()
} catch (Exception e){
// i need to get the code and message as strings
}
}
these are some examples of the exceptions I can get:
You have got the error. [ErrorCode: 400 XYZ]
You have got the error. [ErrorCode: 404 XYZ]
You got error which has no errorCode
and these are the error codes I want for each of these exceptions:
INVALID_TEMPLATE
REQUEST_REJECTED
NO_ERROR_CODE
I tried a few things and this is what I came up with
public class Program {
try {
someFunction(x);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String message = sw.toString();
Matcher m = Pattern.compile(".*:\\s+(.*)\\s+\\[ErrorCode: (\\d+)").matcher(message);
if (m.find()) {
String errorMessage = m.group(1); // You have got the error.
String errorCode = m.group(2); // 400
// Here I want to fetch the error Category based on the errorCode
String errorCategory = XYZ.errorCategory(errorCode);
`//Based on`
the errorCode, errorCategory of INVALID_TEMPLATE which is an enum must be returned
SomeOtherFunc(errorCategory, errorMessage);
}
}
public class XYZ {
private static final Map < String, String > errorMap = new HashMap < > ();
public void populateErrorMap() {
errorMap.put("400", INVALID_TEMPLATE(400, 400));
errorMap.put("404", REQUEST_REJECTED(404, 404));
}
}
public static String errorCategory(String errorCode) {
return errorMap.get(errorCode);
}
Is this optimal or is there a better solution?
Also this is still unable to handle the exception in case there is no error code (should return NO_ERROR_CODE).
How can I archive that?
In real life there are two audiences:
the log handler with a configurable log level (ERROR) and logging (in English) with much info;
the end user with an localized translated message, also with parameters.
The first property is that you probably want a message as format String with Object... parameters. Probably should use MessageFormat.
Sensible would be to support typed parameters.
/** Type-checkable Message Definition. */
public record MessageDef(String format, Class<?>... parameterTypes) {
public void checkFormat() {
... check actual parameters with parameterTypes.length
}
public void checkUsage(Object[] args) {
... check parameter types
}
}
One could make an enum for the error categories. However enums are more suitable for closed domains with a fixed set of values. Extending values in future means that you have created a needless common bottleneck for source version control and so on.
An error is more like an open domain. However if you number them with error codes, an enum gives a nice overview.
The only advantage of error codes is the internationalisation. An Hungarian error message can be easily retrieved.
Then, if you rethrow check exceptions as RuntimeException, like IllegalArgumentException or you own custom ones, you might not want parallel classes: run-time exceptions and categories.
All-in-all I would advise an enum:
public enum MessageType {
INVALID_TEMPLATE(400, Level.ERROR,
new MessageDef("You have got the error in {0}.", String.class)),
...
REQUEST_REJECTED(200, Level.INFO,
new MessageDef("Done."));
public final int code;
public final Level level;
public final MessageDef def;
MessageType(int code, Level level, MessageDef def) {
this.code = code;
this.level = level;
this.def = def;
}
}
One small remark: such little discussion points in the beginning of a project sometimes might be better postponed to a fast refactoring after having written sufficient code. Here an enum might not fit, you might have much re-throwing of exceptions. A premature decision is not needed. And might hamper fast productivity.
Especially as you probably need not mark the code places, you most likely call the same show-error dialog.
I am not sure if I understood your issue properly
If you want to transform your exception code to a custom category this looks shorter:
public class Program {
Map<Integer, String> errorMap = new HashMap<Integer, String>();
errorMap.put(400, "INVALID_TEMPLATE");
errorMap.put(404, "REQUEST_REJECTED");
try {
someFunction (x) ;
} catch (Exception e ) {
SomeOtherFunction(errorMap.get(e.getStatusCode()),errorMessage);
}
}
Otherwise, you could add multiple catches for each exception type if you want to call different functions.
try {
someFunction (x) ;
} catch (IllegalArgumentException e ) {
// do this if exception 1
callThisFunction1()
} catch (IndexOutOfBoundsException e ) {
// do this if exception 2
callThisFunction2()
} catch(ExceptionType3 | Exceptiontype4 ex) {
// do this if exception 3 or 4
callThisFunction3()
}
Also please try to write down your questions better, like give it a proper order.
1)your input
2)your desired output
3)your code
4)the issue
Thank you...

How to make a generic function for Jackson/ObjectMapper in java?

So I have these methods:
private List<ClientRepresentation> toClientRepresentation(String json) {
try {
return objectMapper.readValue(json, new TypeReference<List<ClientRepresentation>>() {
});
} catch (JsonProcessingException e) {
throw new RuntimeException("Could not parse json.");
}
}
private List<RoleRepresentation> toRoleRepresentation(String json) {
try {
return objectMapper.readValue(json, new TypeReference<List<RoleRepresentation>>() {
});
} catch (JsonProcessingException e) {
throw new RuntimeException("Could not parse json.");
}
}
private List<UserRepresentation> toUserRepresentation(String json) {
try {
return objectMapper.readValue(userJson, new TypeReference<List<UserRepresentation>>() {
});
} catch (JsonProcessingException e) {
throw new RuntimeException("Could not parse json.");
}
}
You can see these are similar... Would like to have one method for these... Something like this:
private List<T> toObjectsList(String json, Class classToConvert) {
try {
return objectMapper.readValue(json, new TypeReference<List<classToConvert>>() {
});
} catch (JsonProcessingException e) {
throw new RuntimeException("Could not parse json.");
}
}
Is it possible? How?
Thanks in advance.
Note first that Class<?> can be used to convey only type-parameter-less constructs. Thus, something like List<String> cannot be conveyed with it (only 'List' - any and all lists, unparameterized - that is the only thing Class can convey). If you ever want toObjectsList to return something like a List<Map<String, Object>> you are dead in the water on this: The entire setup fundamentally can't do it. So, first consider whether this is a good idea: You are handicapping yourself, that your toObjectsList method cannot ever return lists of type-argsed types. Presumably, if you're willing to document this and sign up to tacle such needs by not using toObjectsList and writing a custom readValue-based method instead, you're good to go.
Assuming you're on board with this restriction, the question boils down to: How does one construct an STT (Super-Type-Token, that TypeReference thing with the brackets after it) dynamically?
This should be doable, using the TypeFactory class.
For example, constructParametricType(List.class, List.class, classToConvert);.
We then need to address some other errors in your code:
That exception handling is deplorable. You're tossing away all the useful info, and replacing it with entirely useless information. Don't write a catch block that fails to address the issue, unless that catch block preserves all information. Also, by convention exception messages do not end in punctuation.
You are using a <T> in these methods, but you need to declare that T exists, first.
Class, itself, is parameterized.
This gets us to:
private <T> List<T> toObjectsList(String json, Class<T> classToConvert) {
JavaType typeTarget = TypeFactory.defaultInstance()
.constructParametricType(List.class, List.class, classToConvert);
try {
return objectMapper.readValue(json, typeTarget);
} catch (JsonProcessingException e) {
// pass the original exception along as cause, preserving info.
throw new RuntimeException("Could not parse json", e);
}
}
(You may have to cast to List<T>, but I don't think it'll be needed due to some dubious hackery on jackson's part).

How to wrap exceptions handling in helper class with lambda expressions

I am having troubles while trying to refactor exception handling logic in an helper class.
My code uses a repository which accesses a database and might throw the custom exception RepositoryException. If such exception is thrown by the repository, I want my code to catch it and set an error label in the graphical user interface (view):
... // more code
try {
existingCourse = repository.findByTitle(course.getTitle()); // <- throws RepositoryException
} catch (RepositoryException e) {
view.showError(e.getMessage(), course);
return;
}
... // some more code
The point is that this code is repeated several times and I would prefer to have it refactored in an helper class.
This is what I came up to after some experiments:
A custom FunctionalInterface called ThrowingSupplier, which represent the code that throws the exception.
A TransactionManager helper class, with a catcher methods that accepts a ThrowingSupplier
This is the related code (BaseEntity is just a base class for entities in my domain, as you might guess):
// ThrowingSupplier.java
#FunctionalInterface
public interface ThrowingSupplier<T extends BaseEntity> {
T get() throws RepositoryException;
}
/* ------------------------------------------------------ */
// ExceptionManager.java
public final class ExceptionManager<T extends BaseEntity> {
private T result;
private String exceptionMessage;
ExceptionManager() {
}
public boolean catcher(ThrowingSupplier<T> supplier) {
try {
clearResult();
clearExceptionMessage();
result = supplier.get();
return true;
} catch (RepositoryException e) {
exceptionMessage = e.getMessage();
}
return false;
}
// public getters and 'clearers' for attributes
...
}
And this is how I am using this now:
...
em = new ExceptionManager();
... // more code
if (!em.catcher(() -> repository.findByTitle(course.getTitle()))) {
view.showError(em.getExceptionMessage(), course);
return;
}
existingCourse = em.getResult();
... // some more code
Now it seems to me that this does not give any advantages with respect to using directly the try catch in every repository invocation. This is mainly because I need both the return value of the repository method and a way to tell the caller if the repository call has been successful. As a variation I tried to add the showError call inside catcher, but then I must pass view and entity in every invocation of catcher, which I do not like very much as it makes the code less readable.
Is there another way to accomplish this in an elegant manner or it is better to leave the try catch in every call to the repository? Also, what is the standard way to deal with this problem?

Dynamically loading method from external class

I am trying to load methods Customer.cypher and Customer.cypherCBC method from my class Configuration. Customer class is rendering from different environments so few environmets are having cypherCBC() and cypher() method and few are having only cypher() method.
Now i want to check if cypherCBC if not there in Customer class then load cypher() method. My function is so far;
try {
Class<?> customerClass = Class.forName("com.myapp.impl.service.Customer");
Object obj = customerClass.newInstance();
//here getting "NoSuchMethodException" exception
Method methodCBC = customerClass.getDeclaredMethod("cypherCBC", String.class); //line - 7
if(methodCBC.getName().equals("cypherCBC")){
methodCBC.invoke(obj, new String(dbshPass));
System.out.println("CYPHER_CBC: "
+ methodCBC.invoke(obj, new String(dbshPass)));
}else{
Method method = customerClass.getDeclaredMethod("cypher", String.class);
method.invoke(obj, new String(dbshPass));
System.out.println("CYPHER: " + method.invoke(obj, new String(dbshPass)));
}
}catch (Exception e){
e.printStackTrace();
}
Getting an error at line 7.
NoSuchMethodException:
com.myapp.impl.service.Customer.cypherCBC(java.lang.String)
that means for particular environment class Customer doesn't having cypherCBC() method, but ideally it should come in else part and execute cypher() method.
Class<?> client = null;
Object obj = null;
try{
client = Class.forName("com.myapp.impl.service.Client");
obj = client.newInstance();
}catch (InstantiationException ex) {
System.err.println("Not able to create Instance of Class");
} catch (IllegalAccessException ex) {
System.err.println("Not able to access Class");
} catch (ClassNotFoundException ex) {
System.err.println("Not able to find Class");
}
try {
Method methodCBC = client.getDeclaredMethod("cypherCBC", String.class);
System.out.println("CYPHER_CBC: " + methodCBC.invoke(obj, new String(dbshPass)));
}catch (NoSuchMethodException ex) {
System.err.println("Not able to find Method on class");
ex.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
That is exactly what is to be expected: getDeclaredMethod() throws that exception when no method exists that meets your specification. And you are wondering that it throws an exception if the required method is missing? Hint: better read the javadoc next time. Don't assume that something does something, but verify your assumptions!
Besides: read your code again. What is it doing? You are asking "give me the method named 'foo'". And then, your next step is to ask that method "is your name 'foo'". So even without reading javadoc, it should become clear that your logic is flawed.
As solution, you can implement a non-throwing lookup yourself, like
private Method lookupCypher(Class<?> client, String methodName) {
for (Method declaredMethod : client.getDeclardMethods()) {
if (declaredMethod.getName().equals(methodName)) {
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
// so declaredMethod has the given name, and takes one string as argument!
return declaredMethod;
}
}
// our search didn't reveal any matching method!
return null;
}
Using that helper method, you can rewrite your code to:
Method toInvoke = lookupCypher(client, "cypherCBC");
if (toInvoke == null) {
toInvoke = lookupCypher(client, "cypher");
}
toInvoke(obj, new String ...
Or, with the idea from hunter in mind; a much more "OO like" version:
interface CustomerCypherWrapper {
void cypher(String phrase);
}
class NewCustomerWrapper() implements CustomerCypherWrapper {
#Override
void cypher(String phrase) {
new Customer.cypherCBC(phrase);
}
}
class oldCustomerWrapper() implements CustomerCypherWrapper {
#Override
void cypher(String phrase) {
new Customer.cypher(phrase);
}
}
And your client code boils down to:
CustomerCypherWrapper wrapper =
(lookupCypher(..., "cypherCBC") == null)
? new NewCustomerWrapper()
: new OldCustomerWrapper();
wrapper.cypher();
[ I hope you notice that my version A) is easier to read and B) doesn't contain any duplicated code any more. ]
And yes, an alternative implementation of the lookup method could just go like
private Method lookupCyper(Client<?>, String methodName) {
try {
return client.getDeclaredMethod(methodName, String.class);
} catch ....
and return null;
}
... return your public cypherCBC method
But that is an "uncommon practice" in Java. In Java, we ask for permission; instead of forgiveness. Unlike other languages
if you compile the application with a Customer class which has both method,you can use reflection once to check whether the cypherCBC method available or not at runtime, then you can keep that status, you can call the method without using reflection
if(newVersion)
{
customer.cypherCBC(arg);
}
else
{
customer.cypher(arg);
}
But to write a better application,you should use two version baselines.
even though this is a small code fragment you should setup a another module to hide this Customer class and its interactions,that module should have two versions. but your main module has only single version.Now when you you deliver the application , product should be packaged with right version baseline based on compatibility for the target environment.
Although reflection works (as explained in the other answers). if you have control over the Customer class, you can try a non-reflection approach.
interface CBCCypherable {
public String cypherCBC(String pass);
}
You can now have two versions of Customer class, one that implements CBCCypherable and one that doesn't. And when you call it, it looks like this:
Customer c = new Customer();
if (c instanceof CBCCypherable) {
((CBCCypherable)c).cypherCBC(pass);
} else {
c.cypher(pass);
}
What you get with this solution is much simpler code, and as a bonus the compiler will check that you use the correct method name and parameter types. Unlike with reflection, where that's all your job, and you have to run the code to find out if something's wrong.
P.s.: I don't know if this is just sample code or you are really encrypting/hashing passwords here, but it's generally considered a bad idea to roll your own security code.

Java - find the first cause of an exception

I need to check if an exception is caused by some database problem. I receive an Exception and check if its cause contains the "ORA" string and return that (something like "ORA-00001"). The problem here is that the exception I receive is nested inside other exceptions, so if I don't find out if it's an oracle exception, I have to check into the cause of that exception and so on.
Is there a cleaner way to do this? Is there a way to know the first cause (the deep-nested exception) of a given exception?
My current code looks like this:
private String getErrorOracle(Throwable e){
final String ORACLE = "ORA";
if (e.getCause() != null && e.getCause().toString().contains(ORACLE)){
return e.getCause().toString();
} else if(e.getCause() != null){
return getErrorOracle(e.getCause());
} else {
return null;
}
}
In the interests of not reinventing the wheel, if you're using Apache Commons Lang, then look at ExceptionUtils.getRootCause().
Is it worth including a library just for that? Maybe not. But if you already have it on your classpath, it's there for you, and note that it does some things that a 'naive' implementation might not do (e.g. deal with cycles in the cause chain... ugh!)
If you are already on Guava than Throwables.getRootCause() comes to the rescue.
Just traverse the exception chain until you get to an exception with no cause, and then just return that message, if you want the last one.
Your function will only get the first cause, if there is one.
You may want to look at finding the first cause in your package though, as the actual deepest one may be an oracle exception, which is helpful, but unless you can see where you created the problem, you will have a hard time fixing it.
Probably a bit overkill for your usage but I think it is cleaner (and reusable)
interface ThrowablePredicate {
boolean accept(Throwable t);
}
public OracleErrorThrowablePredicate implements ThrowablePredicate {
private static final ORA_ERR = "ORA";
public boolean accept(Throwable t) {
return t.toString().contains(ORA_ERR);
}
}
public class CauseFinder {
private ThrowablePredicate predicate;
public CauseFinder(ThrowablePredicate predicate) {
this.predicate = predicate;
}
Throwable findCause(Throwable t) {
Throwable cause = t.getCause();
return cause == null ? null
: predicate.accept(cause) ? cause : findCause(cause)
}
}
// Your method
private String getErrorOracle(Throwable e){
return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
}
I think that any error that is thrown by oracle will be wrapped in a SQLException (somebody please correct me if wrong). Once you have accessed the SQLException you should be able to call
getErrorCode()
Retrieves the vendor-specific exception code for this SQLException object.
Let me know if this works as I have never tried it :-)
Karl
You could improve your code checking for SQLException
import java.sql.SQLException;
private static final String ORACLE = "ORA";
public String doHandle(Throwable t) {
if (t.getClass().isAssignableFrom(SQLException.class)) {
SQLException e = (SQLException) t;
int errCode = e.getErrorCode();
String state = e.getSQLState();
String msg = e.getMessage();
if (msg.contains(ORACLE)) {
return msg;
}
} else {
if (t.getCause() != null) {
return this.doHandle(t.getCause());
}
}
return "";
}
Also, I think in Oracle "errCode" contains the number associated to ORA-nnnn
In my Spring Boot project for getRootCause IDEA suggest 3 static import:
Spring Core: org.springframework.core.NestedExceptionUtils.getRootCause
Jackson: com.fasterxml.jackson.databind.util.ClassUtil.getRootCause
Guava (Swagger transitive) com.google.common.base.Throwables.getRootCause
Most smart (with cycle check) is Spring NestedExceptionUtils.getRootCause.
But, if your excetion has no cause, method returns null.
In my case it is wrong, so I've done:
#NonNull
public static Throwable getRootCause(#NonNull Throwable t) {
Throwable rootCause = NestedExceptionUtils.getRootCause(t);
return rootCause != null ? rootCause : t;
}
ExceptionUtils.getRootCause(), and Throwables.getRootCause() returns null if the cause of the exception being passed is null.The following method will return the original throwable if an throwable without a cause is being passed as the input parameter.
/**
* #return the root cause of a given throwable.
* If throwable without a cause is being passed, the original throwable will be returned
*/
public static Throwable getRootCause(#NonNull final Throwable throwable) {
List<Throwable> throwableList = ExceptionUtils.getThrowableList(throwable);
return throwableList.get(throwableList.size() - 1);
}
One line solution using core Java API:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new ArithmeticException().initCause(e).getCause());
}
One more solution below works as well:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new Exception().initCause(e).getCause());
}
Both of them will print
java.lang.ArithmeticException: / by zero
I want to add Kotlin extension functions to get root causes:
fun Throwable.rootCause(): Throwable {
return if (cause == null) this else cause!!.rootCause()
}
//Return null if first cause is null
fun Throwable.optRootCause(): Throwable? {
return if (cause == null) null else cause!!.rootCause()
}
Or this one if need to find a cause inside the throwable chain at any points:
fun <T : Throwable> Throwable.isOrContainsCauseOfType(clazz: KClass<T>): Throwable? {
return when {
clazz.isInstance(this) -> this //remove if you want to exclude [this]
cause == null -> null
clazz.isInstance(cause) -> cause
else -> cause!!.isOrContainsCauseOfType(clazz)
}
}
If the exception being thrown is always going to be of a specific type, like OracleException, you can catch just that exception.
For example:
try {
...
} catch(OracleException oe) {
...
}
This would only apply if there are specific Oracle exceptions being thrown. I don't know much about Oracle, so before attempting this you will probably want to find out if that's what's happening.
on 28-01-2015 , i have unable to solve my problem with any of the above solution, so my recommendation is to use :
e.getMessage().toString();
Ps: i am using it on android.

Categories