JAVA lo4j Correct Exception handling and logging - java

For some reason I am missing part of the stack trace, the actual root of the exception.
public void method1(){
try{
method2();
}
catch(SearchException e){
logger.error("Search error", e.getMessage(), e);
}
}
private void method2(){
try{
//Logic which potentially can throw exception
....
....
}
catch(Exception e){
throw new SearchException("Error during execution Module A", e);
}
}
public class SearchException extends Exception{
public SearchException(String message, Throwable cause) {
super(message, cause);
}
}
Anyone knows a reason why I am missing part of stacktrace where fist place exception happened? Could you suggest a correct way of handling/logging exceptions?

super(message, cause);
The message will be the detailMessage of Throwable class. And it will be used in toString method and source cause(Exception) will be ignored.
358 public String toString() {
359 String s = getClass().getName();// class Name
360 String message = getLocalizedMessage();// detailMessage
361 return (message != null) ? (s + ": " + message) : s;
362 }
You may override the toString method in custom Exception class.
class SearchException extends Exception{
String str=null;
public SearchException(String str,Throwable th){
super( th);
this.str=str;
}
public String toString(){
return super.toString() +" - "+ str;
}
}
This customized form will print -
Search error
-----java.lang.NullPointerException-------SearchException: java.lang.NullPointerException - Error during execution Module A

Related

The method in the type is not applicable for the arguments (Class<Main>)?

What I want to do is print a custom error message that prints the class and function that the error resulted in. To get the class I use getClass(). However when I try to run my project I get the following error message:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The method printException(Exception) in the type ExceptionPrinter is not applicable for the arguments (FileNotFoundException, Class<Main>, String, String)
The method printException(Exception) in the type ExceptionPrinter is not applicable for the arguments (ParseException, Class<Main>, String, String)
at Main.main(Main.java)
And I don't know why I can't pass in Class into the function using .class. B/c before I had:
ExceptionHandler.printException(e, getClass() + " main() could not find input file");
where ExceptionPrinter.java printException() looked like this:
public static void printException(Exception e, String message){
System.err.println(message);
printException(e);
}
And that worked fine.
If anyone could help me so that I can pass in the class name to my ExceptionPrinter.java that would be great!
Code
Main.java
public class Main {
public static void main(String[] args) {
try {
...
} catch (FileNotFoundException e) {
ExceptionPrinter.printException(e, Main.class, "main", "Input file not found");
} catch (ParseException e) {
ExceptionPrinter.printException(e, Main.class, "main", "Exception occurred during parsing");
}
}
}
ExceptionPrinter.java
public class ExceptionPrinter {
public static void printException(Exception e){
System.err.println("Error message: " + e.getMessage());
e.printStackTrace();
}
public static void printException(Exception e, Class class, String function, String message){
System.err.println(class + " " + function + "(): " + message);
printException(e);
}
}
Main.java
public class Main {
public static void main(String[] args) {
try {
int a=2/0;
} catch (ArithmeticException e) {
ExceptionPrinter.printException(e, Main.class, "main", "Input file not found");
} catch (NullPointerException e) {
ExceptionPrinter.printException(e, Main.class, "main", "Exception occurred during parsing");
}
}
}
ExceptionPrinter.java
In java class is a keyword, So you can't declare like a variable,
i.e Change Class class to Class c or any
public class ExceptionPrinter {
public static void printException(Exception e){
System.err.println("Error message: " + e.getMessage());
e.printStackTrace();
}
public static void printException(Exception e, Class c, String function, String message){
//System.err.println(class + " " + function + "(): " + message);
printException(e);
}
}
Seems your ExceptionPrinter is not the latest compiled version you are using and probably it's class only has public static void printException(Exception e) method and not the other one. Compile this first. If you would have used build tools that compiles all dependent code, by default then you would not have seen this.
Exception The method printException(Exception) in the type ExceptionPrinter is not applicable for the arguments (FileNotFoundException, Class<Main>, String, String) suggest other overloaded method is not found
Change your overloaded method signature to:
public static void printException(
final Exception execption,
final Class clazz,
final String function,
final String message)
class is a reserved word in Java and can't be used as a parameter name.
Added final because it's a good practice to use.

How to throw an Exception to the method caller inside a try catch body?

I am not able to throw a custom exception from within a try block. The exception doesn't return back to the caller, instead jumps out of the try-catch block and executes the remaining statements (return i; statement in the code).
I know that I don't need the try-catch block for the function "exceptionTester" to run. However I'd like to know the reason for this behaviour. exceptionTester(0) returns 0 instead of the exception being thrown.
public class Test {
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
// TODO: handle exception
}
return i;
}
public static void main(String[] args) {
try {
int in = exceptionTester(0);
System.out.println(in);
} catch (FAException e) {
System.out.println(e.getStatusCode());
}
}
}
public class FAException extends Exception {
private String statusCode;
public FAException(String statusCode, String message, Throwable cause){
super(message,cause);
this.statusCode = statusCode;
}
public String getStatusCode() {
return this.statusCode;
}
}
You are throwing a FAException and you want to re-throw it. Either remove the try-catch entirely, or catch that specific exception (if you insist) like
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (FAException e) {
throw e; // <-- re-throw it.
}
return i;
}
It is also possible to throw a new FAException wrapping some other type of exception in the catch. Which might look like,
} catch (Exception e) {
throw new FAException("Status Code", "Original Message: " + e.getMessage(), e);
}
You are catching any exception that extends from Exception. FAException extends Exception so in your method exceptionTester(int) you are throwing FAException and immediatelly catching it. Since catch block does nothing, it continues in method processing. That's why return is reached.
If you want to catch any exception that can occur in method and rethrow it as your exception then:
public static int exceptionTester(int i) throws FAException{
try {
// some code that throws an exception
// e. g. dividing by zero, accessing fields of null object, ...
} catch (Exception e) {
throw new FAException("Ooops", "Something went wrong", e);
}
return i;
}
If you want to throw an exception when some criteria is met:
public static int exceptionTester(int i) throws FAException {
if (i == 0) {
throw new FAException("IllegalArgument", "arg can not be 0", null);
}
return i;
}
It is simply because you are not rethrowing the caught exception in the main method.
Even if you do this:
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
throw e; --> catching FAException and throwing it to the caller
// 'e' is of type FAException (though you caught it as Exception)
}
return i;
}
It should work, and you won't even hit the "return i" statement.
Otherwise (if no re-throwing, the catch statement will handle the exception and not the caller).
Rest, I agree with the above answer.

Unable to catch custom Exception in java

In my resource method i will get the below exception
#Override
public Response registerByDebitCard(RegistrationRequest registrationRequest,BeanFilter beanFilter) {
try {
RegistrationResponse registrationResponse = registrationService.doRegister(registrationRequest, beanFilter);
return Response.ok(registrationResponse).build();
} catch (CannotCreateTransactionException e) {
LOGGER.error("Error Message is :: {}", e.getMessage());
throw new RegistrationFailureException("MPYR0012", "Due to database technical problem signup failed");
}
}
If i catch above exception it works.
I try to catch this exception using my custom exception class i can't able to catch.Below is my custom Exception class.
public class TransactionManagerDBException extends CannotCreateTransactionException {
/**
* #param msg
*/
public TransactionManagerDBException(String msg) {
super(msg);
}
public TransactionManagerDBException(String msg, Throwable cause) {
super(msg, cause);
}
}
My Resource Method:
#Override
public Response registerByDebitCard(RegistrationRequest registrationRequest,BeanFilter beanFilter) {
try {
RegistrationResponse registrationResponse = registrationService.doRegister(registrationRequest, beanFilter);
return Response.ok(registrationResponse).build();
} catch (TransactionManagerDBException e) {
LOGGER.error("Error Message is :: {}", e.getMessage());
throw new RegistrationFailureException("MPYR0012", "Due to database technical problem signup failed");
}
}
Now i am unable to catch this exception.Is their anything wrong in my exception handling.please explain what's wrong with my approach
Any help will be greatly appreciated!!!!
Your TransactionManagerDBException IS-A CannotCreateTransactionException. But the reverse is not true. If your registrationService does throw a CannotCreateTransactionException, it is NOT a TransactionManagerDBException.
If you cannot change the doRegister method to throw a TransactionManagerDBException, you can only use a catch block using CannotCreateTransactionException.

Full path of an exception in java

I am trying to throw a custom exception
class NumberFormatException extends Exception
{
public NumberFormatException() {}
//Constructor that accepts a message
public NumberFormatException(String message)
{
super(message);
}
}
Later, I am throwing this exception using
throw new NumberFormatException("Exception found");
and later on catching it using
catch(NumberFormatException e)
{
System.out.println(e);
}
It prints something like
NumberFormatException: Exception found
Is it possible to print something like:
java.lang.NumberFormatException: Exception found
The constraint is the catch code can't be modified i.e
catch(NumberFormatException e)
{
System.out.println(e);
}
You are trying to get Canonical name of exception class and here is how you can get it:
catch(NumberFormatException e)
{
System.out.println(e.getClass().getCanonicalName());
}
Refer javadoc for more : getCanonicalName
Override toString In your NumberFormatException class :
class MyException extends Exception{
String message;
public MyException(String string) {
this.message = string;
}
#Override
public String toString() {
String s = getClass().getCanonicalName();
String message = this.message;
return (message != null) ? (s + ": " + message) : s;
}
}
Source : Throwable
Here is a full code testing the method :
package first;
class MyException extends Exception{
String message;
public MyException(String string) {
this.message = string;
}
#Override
public String toString() {
String s = getClass().getCanonicalName();
String message = this.message;
return (message != null) ? (s + ": " + message) : s;
}
}
public class TestingMyException{
public static void main(String[] args) {
try{
throw new MyException("This works !");
}catch(MyException e){
System.out.println(e);
}
}
}
Output
first.MyException: This works !
Since my class is defined in the package named first of my root, the result prints first.MyException.
So you also have to check if your class is not defined in the default package. Otherwise, you'll not get anything but :
MyException: This works !

Java casting (dynamic)

I'm sure this is a very stupid question, but still I would like to know, is it possible to cast the global variable cause dynamically, in other words without using the instanceof operator ?
The reason for this question is, I feel the instanceof operator is not doing anything great here, it's just casting the cause statically, but in either case it's creating a new IOException(cause)
Because the cause is of type Object, I had to type cast it to either String or Throwable.
private Object cause; // global variable
//...
if (failed)
throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause);
Below is the actual code snippet where the two overridden methods will be called asynchronously.
public class Command implements ResponseListener {
private Object cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = status + " received for " + command.split(":")[0] + message;
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
this.cause = cause;
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause);
}
}
Why not having always a Throwable for your cause variable ? Throwable seems more adapted to express a failure than a String. Plus it avoids you to use the "ugly" operator instanceof.
public class Command implements ResponseListener {
private Throwable cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = new Throwable(status + " received for " + command.split(":")[0] + message);
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
this.cause = cause;
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw new IOException(cause);
}
}
Update after discussion below:
public class Command implements ResponseListener {
private String cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = status + " received for " + command.split(":")[0] + message;
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
if(cause.getMessage().isEmpty()) {
this.cause = cause.toString();
}
else {
this.cause = cause.getMessage();
}
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw new IOException(cause);
}
}
As there is no common superclass of String and Throwable that would be acceptable as parameter to IOException, you have to cast it to one or the other, and in order to determine what to cast it to, you have to use instanceof.
Class.cast and Class.isAssignableFrom methods may be used as dynamic counterparts of cast and instanceof operators respectively.

Categories

Resources