I would like to know what the exception instance was in this situation:
try {
// some risky actions
} catch (Exception e) {
System.out.println("Get instance name there");
}
How can I achieve this?
Here you go:
try {
throw new ArithmeticException();
} catch (Exception e) {
System.out.println( e.getClass().getCanonicalName());
}
Output:
java.lang.ArithmeticException
The type of the exception is shown as part of the output of:
e.printStackTrace();
To get it programmatically you can use:
String exceptionClassName = e.getClass().getName();
It is poor form to have logic depending on exception sub types within a catch block. Sonar will flag this as a code violation (squid S1193).
Instead you should add multiple catch blocks to catch different types of exceptions:
try {
readFile(fileName);
}
catch (java.io.IOException e) {
LOG.error("Error accessing file {}", fileName, e);
}
catch (java.lang.IllegalArgumentException e) {
LOG.error("Invalid file name {}", fileName, e);
}
Note: Since Log4j 2 (and SLF4J 1.6+) you can add a throwable as the last parameter and it will be recognized as such. So the above will work!
Since Java 7 you can also do a multi-catch:
}
catch (java.io.IOException | java.lang.IllegalArgumentException e) {
LOG.error("Could not read the file {}", fileName, e);
}
The benefit of the multi-catch is that you can handle multiple exception types within a single catch block without having to revert to a common super class (like java.lang.Exception) that would include exception types you didn't want to handle.
Default exception logging is something like
try
{
//
}
catch (Exception e)
{
e.printStackTrace();
}
This will print the stacktrace of the exception to system.err
If you are looking to add some contextual information, you can take a look at Apache Commons ContextedRuntimeException
public static void main(String[] args) {
try {
doSomething();
} catch (ContextedRuntimeException e) {
System.out.println(e.getMessage());
System.out.println(e.getContextEntries());
}
}
private static void doSomething() {
int divisor = 0;
int dividend = 100;
int result;
try {
result = dividend / divisor; // Just throw an exception to test things....
System.out.print("DIVISION RESULT: "+result);
} catch (ArithmeticException e) {
throw new ContextedRuntimeException("Oops..division by zero not allowed", e)
.addContextValue("Divisor", divisor)
.addContextValue("Dividend", dividend);
}
}
would output:
Oops..division by zero not allowed
Exception Context:
[1:Divisor=0]
[2:Dividend=100]
---------------------------------
[(Divisor,0), (Dividend,100)]
Related
Assuming we are talking about all the exceptions that extends base Exception class,
is:
try {
some code;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
catch (MyOwnException e)
{
e.printStackTrace();
}
same as:
try {
some code;
}
catch (Exception e) {
e.printStackTrace();
}
I am wondering in which case I MUST use the former one?
In the 2nd option Exception will catch all exception, not only those explicitly listed in the first option.
Use the 1st option if you want to catch only selected exceptions, and respond differently to each.
If you want to catch only selected exceptions, and have the same response to all of them, you could use:
catch (InterruptedException | ExecutionException | MyOwnException e)
{
e.printStackTrace();
}
It is good practice to use Exception sub classes rather than Exception class. If you use Exception then it would be difficult to debug.
Here is a link for reference
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices/#3
If you have multiple exceptions which all are extending from...we'll say IndexOutOfBoundsException, then unless you specifically want to print a different message for StringIndexOutOfBoundsException or another sub-class you should catch an IndexOutOfBoundsException. On the other hand if you have multiple exceptions extending from the Exception class, it is proper format to create a multi-catch statement at least in JDK 1.8:
try {
// Stuff
}catch(InterruptedException | ClassNotFoundException | IOException ex) {
ex.printStackTrace();
}
The former one where you create multiple catch statements is if you were trying to do what I said before.
try {
// Stuff
}catch(StringIndexOutOfBoundsException se) {
System.err.println("String index out of bounds!");
}catch(ArrayIndexOutOfBoundsException ae) {
System.err.println("Array index out of bounds!");
}catch(IndexOutOfBoundsException e) {
System.err.println("Index out of bounds!");
}
I want to get error message using java when exception are generated.
now I have java code with following scenario:
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e)
}
}
method second(){
try{
my code
}catch(Exception e){
throw new Exception("Exception generate in second method",e);
}
}
now when the first method execute then I get only "Exception generate in second method" message but there is some other message printed on console by java so how to get that console error message.
Note: I have already try with e.getMessage(); and e.printStackTrace();
Every exception has a cause that you can get with getCause(). You can go recursively down them until you get to the root cause. Here is your example with a utility that dumps the exception with all its causes like the console does.
private void first() {
try {
second();
} catch (Exception ex) {
Log.e("CATCH", getExceptionDump(ex));
}
}
private void second() {
try {
throw new UnsupportedOperationException("We don't do this.");
} catch (Exception ex) {
throw new RuntimeException("Exception in second()", ex);
}
}
private String getExceptionDump(Exception ex) {
StringBuilder result = new StringBuilder();
for (Throwable cause = ex; cause != null; cause = cause.getCause()) {
if (result.length() > 0)
result.append("Caused by: ");
result.append(cause.getClass().getName());
result.append(": ");
result.append(cause.getMessage());
result.append("\n");
for (StackTraceElement element: cause.getStackTrace()) {
result.append("\tat ");
result.append(element.getMethodName());
result.append("(");
result.append(element.getFileName());
result.append(":");
result.append(element.getLineNumber());
result.append(")\n");
}
}
return result.toString();
}
The message in the Exception constructor argument is not printed in the exception detail.
You can simply use this code to print the message :
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e.getMessage())
}
}
Hope this solves your problem
Why you cannot use print stack trace ?
Because A throwable contains a snapshot of the execution stack of its thread at the time it was created. (see Throwable)
It implies that, if you want to print the stack trace you need to use the printStackTrace() method BUT in your second method !
method second(){
try {
my code
} catch(Exception e) {
e.printStackTrace();
throw new Exception("Exception generate in second method",e);
}
}
Or using a the tricky method setStackTrace and using the printStackTrace() in first
method second(){
try {
my code
} catch(Exception e) {
Exception ex = new Exception("Exception generate in second method",e);
ex.setStackTrace(e);
throw ex;
}
}
method first(){
try {
second();
} catch(Exception e) {
e.printStackTrace();
}
}
You can print the cause of the exception you get. Try this:
method first(){
try{
second();
}catch(Exception e){
System.out.println("Error:> "+e);
if (e.getCause() != null) {
System.out.println("Cause:> " + e.getCause());
}
}
}
I believe this is the console message you want to achieve:
Error:> java.lang.Exception: Exception generate in second method
Try this code, when the catch block of the second method throws an exception the second method should declare it as throws or put a nested try catch within the catch block.
The exception is propagated to the first() method which is handled by its catch block.
public class Test {
public void first() {
try {
second();
} catch (Exception e) {
System.out.println("Error:> " + e);
}
}
public void second() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
throw new Exception("Exception generate in second method", e);
}
}
public static void main(String ars[]) {
Test test = new Test();
test.first();
}
}
Sonar gives a major violation error ("Preserve Stack Trace") for the following code. Following method is used to throw an exception. What are the steps should I take to overcome this violation?
public void exceptionHandler(String exception) throws PhDashException {
String exceptionMsg = exception.replaceAll("-", "_");
ExceptionPhDash pHDashExceptionMapper = new ExceptionPhDash();
try {
pHDashExceptionMapper = new ObjectMapper().readValue(exceptionMsg, ExceptionPhDash.class);
} catch (JsonParseException e) {
LOGGER.info(e.getMessage());
} catch (JsonMappingException e) {
LOGGER.info(e.getMessage());
} catch (IOException e) {
LOGGER.info(e.getMessage());
}
throw new PhDashException(pHDashExceptionMapper.getMessage());
}
You've logged each exception; that should be enough as far as preserving information is concerned like below,
LOGGER.info("Unexpected Exception has occurred", e);
Or You should re throw the PhDashException if you can, because, you should be enough as far as preserving information is concerned
throw new PhDashException(pHDashExceptionMapper);
when I debug the below code, there is an SmbException and goes catch block line sb.append(pLogger.reportError(pStr, e));, but it does not go into the method reportError().
what is the reason behind this. please advise if any changes.
try {
sfos = new SmbFileOutputStream(sFile);
} catch (SmbException e) {
sb.append(pLogger.rError(pathStr, e));
}
below is rError() method
public String rError(String pxString,Exception e){
String errorToMailStr=null;
abcd="Verifying # "+pxString+"::Error ["+e.getMessage()+"]";
logger.debug("Error when verifying # "+pxString+":Error ["+gMsg(e)+"]");
return abcd;
}
at line logger.debug("Issue "+pxString+":Error ["+gMsg(e)+"]");
is going to below method and ends.
public abstract class ReflectiveCallable {
public Object run() throws Throwable {
try {
return runReflectiveCall();
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
Based on what you have revealed here, there is a problem in getExceptionMsg()
I'm working on some server-side code that wraps all exceptions before passing them to the client side, due to this all client facing methods have the following code
try{
DoSomething();
} catch (ExceptionA e) {
throw new CustomException(AType, e);
} catch (ExceptionB e) {
throw new CustomException(BType, e);
} catch (Exception e) {
throw new CustomException(Unexpected, e);
}
to have this repeated in every method seems to violate the DRY principle and I was wondering what the best way to refactor it would be. For instance I was thinking a wrapper method such as:
private void wrapException(Exception e) {
if (e instanceof ExceptionA) {
throw new CustomException(AType, e);
}
etc...
Take a look at AspectJ soften exception.
Also look at Guava's Throwables.
There is also Lamboks sneaky exception.
The other option is to use Anonymous object instances aka closures.
public abstract class Wrapper {
public void execute() {
try {
// do some boiler plate before
this.wrap();
// do some boiler plate after.
} catch (ExceptionA | ExceptionB ex) {
Type t = determineType(ex);
throw new CustomException(t, ex);
}
}
public void abstract wrap();
}
Now in your code you do something like:
new Wrapper() {
public void wrap() {
DoSomething();
}
}.execute()
This is possible in Java7 and up:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Copy-paste example from above doc:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
This is one way to go about it:
Exception caughtEx = null;
String extraInfo = null;
try{
DoSomething();
} catch (ExceptionA e) {
caughtEx = e;
extraInfo = AType;
} catch (ExceptionB e) {
caughtEx = e;
extraInfo = BType;
} catch (Exception e) { // catching Exception is usually a bad idea, just let it bubble up without catching...
caughtEx = e;
extraInfo = Unexpected;
}
if (caughtEx != null) throw new CustomException(extraInfo, caughtEx);