When throw exception, I found that always included java.lang.exception or javax.ssl.xxxx and so on, I just want to get only messages but not including exception type, how can I do it?
As exception has many types, I can not just filter string start with, is it available to do so?
Find below a small snippet as demonstration for my comment
try {
int i = 1 / 0;
} catch (Exception e) {
System.out.println("exception = " + e);
System.out.println("getMessage = " + e.getMessage());
}
output
exception = java.lang.ArithmeticException: / by zero
getMessage = / by zero
Related
I was writing a code to show examples of try/catch and I notice that the same catch NumberFormatException was triggered or not depending on where I use it. This is the code:
public class Main {
public static void main(String[] args) {
System.out.println("3/0 => Result: " + divide(3,0)); // returns 3/0 => Result: null
System.out.println("6/2 => Result: " + divide(6,2)); // returns 3/0 => Result: 3
// System.out.println("6/home => Result: " + divide(Integer.parseInt("home"),1));
try {
System.out.println("6/home => Result: " + divide(Integer.parseInt("home"),1));
} catch (NumberFormatException e) {
System.out.println("Error type: NumberFormatException (MAIN METHOD)");
}
}
static Integer divide(int n1, int n2) { // we used Integer (wrapper class) to be able to return null
int result = 0;
try {
result = n1 / n2;
} catch (ArithmeticException e) {
System.out.println("Error type: ArithmeticException");
return null;
} catch (NumberFormatException e) {
System.out.println("Error type: NumberFormatException");
return null;
}
return result;
}
}
The code returns:
Error type: ArithmeticException
3/0 => Result: null
6/2 => Result: 3
Error type: NumberFormatException (MAIN METHOD)
But if I enable the 3rd line:
System.out.println("6/home => Result: " + divide(Integer.parseInt("home"),1));
And disable the try/catch inside main method the NumberFormatException inside the divide method does not trigger and it crash the program.
Can anyone explain why? I am using the same exception type, why it works inside the main method but it does not work inside the divide method?
It's because the Integer.parseInt method is called from the main method and not inside try / catch block. Look at the stack trace that should be printed out.
Exception in thread "main" java.lang.NumberFormatException: For input string: "home"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at Main.main(Main.java:6)
The last line (Main.main(Main.java:6)) is giving you a clear hint from where the exception was thrown out in your code.
Catching exceptions is depending on the exception happening inside the corresponsing try{} block. By disabling the try / catch inside the main method the occuring number format exception is not in any try{} block anymore and therefore "crashes" your program. The try / catch inside the divide method is in that case never even reached, as the exception happens while the thread is executing the code 'Integer.parseInt("home")' which is outisde of that block / inside your main method.
#Test
public void test() throws Exception {
driver.navigate().to(someurl);
Thread.sleep(2000);
try {
obj.assertPageTitle1("Title");
obj.clickButton();
obj.assertPageTitle2("Title");
obj.assertPageTitle3("TitleWithError");
} catch (Error e) {
System.out.println("Exception is - " + e);
}
}
Log: Exception is - java.lang.AssertionError
How can I add line number(where was error) in the message which show error in log?
The most recent called method is appeared in the stacktrace's first element.
Try
e.getStackTrace()[0].getLineNumber();
Small example:
try {
String s = null;
s.toLowerCase();
} catch (Exception e) {
System.out.println("Line number is: " + e.getStackTrace()[0].getLineNumber());
}
Note: You can always print stacktrace by using e.printStackTrace() to see the more verbose result.
public class ExceptionDemo {
public static void main(String[] args) {
try {
int x = Integer.parseInt(args[0]);
System.out.printf("try: x = %d\n", x);
int z = 42 / x;
System.out.printf("try: z = %d\n", z);
return;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException: " + e.getMessage());
} catch (NumberFormatException e) {
System.out.println("NumberFormatException: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("ArithmeticException: " + e.getMessage());
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
System.out.println("finally");
}
System.out.println("end");
}
}
When I try input 0,java catches "ArithmeticException".
The question is how java knows ArithmeticException is ArithmeticException?
So I look for ArithmeticException class.
public class ArithmeticException extends RuntimeException {
private static final long serialVersionUID = 2256477558314496007L;
/**
* Constructs an {#code ArithmeticException} with no detail
* message.
*/
public ArithmeticException() {
super();
}
/**
* Constructs an {#code ArithmeticException} with the specified
* detail message.
*
* #param s the detail message.
*/
public ArithmeticException(String s) {
super(s);
}
}
There is no special in ArithmeticException class.
How the java detect the error "42/0" is the ArithmeticException?
Just because ArithmeticException extends RuntimeException?
I guess your question is, how does Java know that it should throw an ArithmeticException when you try to divide by 0?
Because the language specification says so:
JLS Section 15.17.2
...On the other hand, if the value of the divisor in an integer division is 0, then an ArithmeticException is thrown.
That's it. Because it says so, it does so.
I can't explain this any further because we can't know the implementations of operators like / unless we look at the source code of the Java compiler. If it's a method, we can just read the source code of the JDK.
The way try/catch work is as following (taken from here)
The catch block contains code that is executed if and when the
exception handler is invoked. The runtime system invokes the exception
handler when the handler is the first one in the call stack whose
ExceptionType matches the type of the exception thrown. The system
considers it a match if the thrown object can legally be assigned to
the exception handler's argument.
So basically when an exception is thrown, the code will walk through all of your catch statement to see if any of the catch clause matches the exception ("match" = "can be assigned to the exception handler's argument"). If there's a match, the corresponding exception handler will be invoke. If there's none, the exception will be bubbled up to the caller.
Another way to look at this is if you have your code like this:
try {
// 42/ 0
} catch (Exception e) {
System.out.println("Got Exception");
} catch (ArithmeticException e) {
System.out.println("ArithmeticException: " + e.getMessage());
}
Then you'll see that it will always print "Got Exception" and not the "ArithmeticException ..."
For code quality reasons, I would like to replace a try catch block inside my code with an if condition in order to avoid using a FrontendException.
Here is my code :
Schema mySchema = new Schema();
mySchema.add(new Schema.FieldSchema("myInteger", DataType.INTEGER));
mySchema.add(new Schema.FieldSchema("myBoolean", DataType.BOOLEAN));
Schema tupleSchema = new Schema();
try {
tupleSchema.add(new Schema.FieldSchema("ARRAY_ELEM", mySchema, DataType.BAG));
} catch (FrontendException e) {
tupleSchema = new Schema(new Schema.FieldSchema(getSchemaName("myClass", input), DataType.DOUBLE));
}
return tupleSchema;
Is it possible to replace this code using an if else condition? This way I won't have to use this type of Exception and that would be better for SonarQube.
Any ideas?
The exception thrown by the Schema.FieldSchema constructor is deterministic. Here is the code of the constructor;
public FieldSchema(String a, Schema s, byte t) throws FrontendException {
alias = a;
schema = s;
log.debug("t: " + t + " Bag: " + DataType.BAG + " tuple: " + DataType.TUPLE);
if ((null != s) && !(DataType.isSchemaType(t))) {
int errCode = 1020;
throw new FrontendException("Only a BAG, TUPLE or MAP can have schemas. Got "
+ DataType.findTypeName(t), errCode, PigException.INPUT);
}
type = t;
canonicalName = CanonicalNamer.getNewName();
}
So the exception is thrown if;
the Schema given is null
the DataType given is not a schema type
You know in advance whether the exception will be thrown. In your case it is not so you can safely ignore the exception as it can never be thrown. You can remove the code in the catch block. You may as well replace it with;
throw new IllegalStateException("Summon Cthulhu");
Its a similar case to getting the UTF-8 charset;
String test = "abc";
byte[] bytes;
try {
bytes = test.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
//Can never happen although the compiler forces us to catch it
}
although the method getBytes can throw an exception if the charset is not supported, the UTF-8 charset is always guaranteed to be supported.
I have the following java code:
if (ps.executeUpdate() != 1)
{
// Error - did not insert one row
String err = "insert unable to insert LocalUsage data: " + usg.toString();
Logger.log(err, _MODULE_CLASS, Logger.DEBUG);
throw new DaoException(err);
}
The problem if the query had a foreign key exception, then it will be thrown but it will never get to inside the if. what should I do so that it will get inside the if and output the log I have?
The problem is that this if condition is inside a try catch block, and it is going to the catch and never enters to the if condition.
executeUpdate() might throw an SQLException, as is described in its API documentation. You might want to catch that exception.
int count;
try {
count = ps.executeUpdate();
} catch (SQLException e) {
throw new DaoException("Exception while executing update: " + e.getMessage());
}
if (count != 1) {
// ...
}
As the docs states executeUpdate() may throw an exception so your code flow will fail and you will not be able to do any processing afterwards incase your exception handling is not proper.
Which I think is happening in your code right now.
While doing database call I would suggest you do it like this:
int operationStatus;
try {
operationStatus = ps.executeUpdate();
} catch(SQLException exp) {
final String message = "SQL Exception while calling executeUpdate()";
logger.error(message, exp);
throw new DAOException(message, logger);
} catch(Exception exp) {
final String message = "Exception while calling executeUpdate()";
logger.error(message, exp);
throw new DAOException(message, logger);
} finally {
//you may wish to clean up resources if they are not going to be used after this point.
}
if(operationStatus < 0) {
//Next steps
}