I have the following java code :
public void someMethod(){
try{
// some code which generates Exception
}catch(Exception ex1) {
try{
// The code inside this method can also throw some Exception
myRollBackMethodForUndoingSomeChanges();
}catch(Exception ex2){
// I want to add inside `ex2` the history of `ex1` too
// Surely , I cannot set cause of `ex2` as `ex1` as `ex2`
// can be caused by it's own reasons.
// I dont want `ex1` details to be lost if I just throw `ex2` from my method
}
}
}
How to do it ?
EDIT : Actually this happens in my service layer and I have controller advice for logging. Hence I don't want to add 2 loggers here.
You can add ex1 to the supressed exceptions in ex2 via the method addSuppressed before rethrowing it.
Quick code example:
public static void main(final String[] args) {
try {
throw new IllegalArgumentException("Illegal Argument 1!");
} catch (final RuntimeException ex1) {
try {
throw new IllegalStateException("Illegal State 2!");
} catch (final RuntimeException ex2) {
ex2.addSuppressed(ex1);
throw ex2;
}
}
}
will produce the exception output:
Exception in thread "main" java.lang.IllegalStateException: Illegal State 2!
at package.main(Main.java:26)
Suppressed: java.lang.IllegalArgumentException: Illegal Argument 1!
at package.main(Main.java:20)
Related
This question already has answers here:
Understanding checked vs unchecked exceptions in Java
(21 answers)
Closed 2 years ago.
finally block would execute if an exception is thrown in try block here:
public class ExceptionTest{
public static void main(String args[])
{
System.out.println(print());
}
public static int print()
{
try
{
throw new NullPointerException();
}
finally
{
System.out.println("Executing finally block");
}
}
}
output:
Executing finally block
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.print(ExceptionTest.java:11)
at ExceptionTest.main(ExceptionTest.java:4)
In the other hand finally won't be called in this code right here:
public class ExceptionTest{
public static void main(String args[])
{
System.out.println(print());
}
public static int print()
{
try
{
throw new Exception();
}
finally
{
System.out.println("Executing finally block");
}
}
}
output:
ExceptionTest.java:11: error: unreported exception Exception; must be caught or declared to be thrown
throw new Exception();
^
1 error
why it is cool with NullPointerException class but it complains when it comes to Exception class?
NullPointerException is an unchecked exception. Check this guide.
Here is an example of a try and catch block which catches everything:
try {
//Do Something
}
catch (Exception e) {
System.out.println("Something went wrong.");
}
finally {
System.out.println("The 'try catch' is finished.");
}
I have
public static void main(String[] args){
String text = parseXml(XmlText); // Exception occurs here in called method.
}
I want to check the type of exception occurred while parsing xml and call another method accordingly like this.
if(thisException){
String text = anotherMethod(xmlText);
}
How can I achieve this.
Thanks in advance.
Use a try catch for this
public static void main(String[] args){
try {
String text = parseXml(XmlText);
// do something
}
catch ([THE EXCEPTION TYPE] ex){
String text = anotherMethod(xmlText);
// do something else
}
}
Your application will still crash if the exception is not handled in your catch. You can also catch different types of exceptions and handle them accordingly by adding another catch-clause. E.g.
catch (EXCEPTION1 EX) {
// ...
}
catch (EXCEPTION2 EX) {
// ...
}
I have a utility method for timing and logging various queries all over the project.
The problem is, when looking at crashlytics now all unrelated crashes are joined together into one crash-instance.
Can I catch all exceptions on the utility method, and throw them after removing that method from the stack?
The environment is Android (Java)
UPDATE:
based on #Dhananjay's answer below, here's my code:
public static Cursor get(...) {
try {
// my utility code
} catch (RuntimeException e) {
throw cleanException(e);
}
}
private static RuntimeException cleanException(RuntimeException e) {
try {
StackTraceElement[] stackTrace = e.getStackTrace();
StackTraceElement[] subTrace = new StackTraceElement[stackTrace.length - 1];
System.arraycopy(stackTrace, 1, subTrace, 0, subTrace.length);
e.setStackTrace(subTrace);
return e;
} catch (Throwable ignored) {
return e;
}
}
This approach might solve your problem: Set the stacktrace of the exception in the utility logging method to exclude the utility method itself, and then throw the exception, here is a working example, you can modify it to eliminate any StackTraceElement you want to:
package test;
public class TestMain {
public static void main(String args[]) throws Exception {
try {
apiCall();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void apiCall() throws Exception {
logAndThrow();
}
public static void logAndThrow() throws Exception {
Exception e = new Exception();
StackTraceElement[] cleanedUpStackTrace = new StackTraceElement[e.getStackTrace().length -1];
// Eliminate this mehod i.e. logAndThrow's stack trace entry (i.e. the first one) in cleanedUpStackTrace
System.arraycopy(e.getStackTrace(), 1, cleanedUpStackTrace, 0, cleanedUpStackTrace.length);
for(StackTraceElement ste : cleanedUpStackTrace) {
System.out.println(ste.getMethodName());
}
e.setStackTrace(cleanedUpStackTrace);
throw e;
}
}
Here is the output of this program, the logAndThrow method is not present in stack trace now:
apiCall
main
java.lang.Exception
at test.TestMain.apiCall(TestMain.java:33)
at test.TestMain.main(TestMain.java:25)
I am doing Android Unit Test Case Execution and for Negative Test Case I should get exception, but for some API's Exception is not caught.
Please do find the example below:
public void testInsertSenderType_n() {
DBSms obj = new DBSms(getContext());
obj.open();
int i =0;
int a =0;
boolean result = true;
i=obj.GetToatlCount();
obj.insertSmsText(i+1,"Hello to testInsertSenderType_n");
a=obj.TotalcountSms("Inbox");
try
{
obj.insertSenderType(-100, "Richard", "Inbox", 0);
}
catch (Exception e)
{
// TODO: handle exception
result = false;
}
assertEquals(a,obj.TotalcountSms("Inbox"));
assertEquals(false,result);
obj.close();
}
Here in, obj.insertSenderType(-100, "Richard", "Inbox", 0); should throw an exception. But it is not thrown.
Please do guide where can I be Wrong.
I use following method to expect proper exception:
try {
doSomethingToProvokeException();
fail("there ought to be an exception dude, but was not");
} catch(ExeptionIHaveProvoked ex) {
doAssertionnsonThrowsException
}
You do not need variables to keeps exception state. As for why no exception is thrown in your code - nobody cann tell it to you, unless you provide source of object.
I have used log4j for looging error log using FileAppender. The problem is its logging the same error two times in a log file when the below situation
Case1:
Class1 :
public void func(){
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop(){
try{
//error oocurs here
}catch(FileNotFoundException fe){
logger.log(2,fe);
}
}
Error :
Class2 .FileNotFoundException
at Class2.prop(Class2.java:3)
at Class1.func(Class1.java:4)
Log File :
FileNotFound exception
FileNotFound exception
But its logging the error one time for the below case.
Case2 :
Class1 :
public void func(){
try{
new Class2.prop()
//error oocurs here
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop(){
try{
}catch(FileNotFoundException fe){
logger.log(2,fe);
}
}
Error :
Class2 .IOException
at Class1.func(Class1.java:4)
Log File :
IOException exception
Help me what should i do to log the error only one time in a log file whereever it is.
But its logging the error one time for the below case.
That's because you're handling the exception:
Class1:
public void func() {
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop() throws IOException {
try{
//error oocurs here
}catch(FileNotFoundException fe){
logger.log(2,fe);
throw fe;
}
// Here!!!!!
}
In your catch block of the class2 ( after your //error oocurs here ) you log the exception, that's what you've got on your logs.
But since you are just logging the exception, you're telling the program that the exception has been controlled somehow, or handled ( which is more appropriate) and the program continues it's flow to the line where I added the comment // Here!!!!!
Later in class1, since the exception was handled, nothing happens in your try/catch block and your second exception is never logged ( as you expected ) because it never happened.
If you want to see two logs ( which I think it's unnecessary ) you should re-throw the exception as I did in your class2 and plus, modify the method signature to mark indicate it throws an IOException.
That way you will have two logs.
Better will be like this:
Class1:
public void func() {
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop() throws IOException {
//error oocurs here
}
In class 2 you don't handle the exception, you just let it go through the caller. In the stacktrace you'll have the information anyway.
I hope this helps.
In your log4j configuration, do you have the logger used in Class 2 being sent to your appender twice?