I have a code that executes multiples commands, I need to track the steps to track failures based on the step number
How to get a value of a field inside a method from exception handler I don't want to use try/catch clause.
Maybe it's possible to write it annotation on the test Method with Aspect J?
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {
@Test
public void runCode(){
Integer test = 0;
System.out.println(test);
test = 1;
System.out.println(test);
if(true) throw new RuntimeException(" error thrown");
test = 2;
System.out.println(test);
}
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public void handleValidationException(RuntimeException throwable) {
//TODO how to get here the last step
System.out.println("failed as step: ");
}
}
Just to clarify My code not really throwing an exception I might get an exception from reading a file, writing a file etc.. So for unexpected an Exception how can i get the last step
CodePudding user response:
Add test
to the exception message:
throw new RuntimeException("error thrown " test);
Then inspect it in the catch:
public void handleValidationException(RuntimeException throwable) {
String step = throwable.getMessage().replaceAll("error thrown (\\d )", "$1");
System.out.println("failed at step: " step);
}
CodePudding user response:
The values of the local variables are lost, when an exception is thrown. No way to get them back.
The only way to track them is to secure them before the exception is thrown. This may look like below – based on the suggestion from Johannes Kuhn's comment to the answer from Bohemian and that answer:
@RunWith( SpringJUnit4ClassRunner.class )
public class Test
{
@Test
public void runCode()
{
Integer test = 0;
try
{
System.out.println( test );
test = 1;
System.out.println( test );
if( true ) throw new RuntimeException( " error thrown" );
test = 2;
System.out.println( test );
File file = new File( "DefinitelyNonExisting.file" );
InputStream inputStream = new FileInputStream( file );
test = 3;
System.out.println( test );
}
catch( final Throwable t )
{
throw new RuntimeException( test.toString(), t );
}
}
@ExceptionHandler( RuntimeException.class )
@ResponseBody
public void handleValidationException( RuntimeException throwable )
{
Integer testStep = Integer.valueOf( throwable.getMessage() );
System.out.printf( "failed at step: %d with exception %s%n", testStep, throwable.getCause() );
}
}
Some error handling should be added …
Of course you can create your own exception class, derived from RuntimeException
that takes the value of test
as an additional argument for its constructor, perhaps plus some additional information that might be useful for your diagnosis of the failure, and throw that in the catch
block.
And yes, usually you should never catch Throwable
. But this rule is for production code, not for test cases.