Skip to content

Commit

Permalink
Improve exceptions message for lifecycle graceful stop/shutdown attempts
Browse files Browse the repository at this point in the history
Improve exception message to be less confusing and highlight miss leading
suppressed exception nature and origin.
  • Loading branch information
MishaDemianenko committed Jul 11, 2017
1 parent 4f873f5 commit b6f0120
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
Expand Up @@ -415,7 +415,10 @@ public void init()
} }
catch ( Throwable se ) catch ( Throwable se )
{ {
e.addSuppressed( se ); LifecycleException lifecycleException = new LifecycleException( "Exception during graceful " +
"attempt to shutdown partially initialized component. Please use non suppressed" +
" exception to see original component failure.", se );
e.addSuppressed( lifecycleException );
} }
if ( e instanceof LifecycleException ) if ( e instanceof LifecycleException )
{ {
Expand Down Expand Up @@ -451,7 +454,10 @@ public void start()
} }
catch ( Throwable se ) catch ( Throwable se )
{ {
e.addSuppressed( se ); LifecycleException lifecycleException = new LifecycleException( "Exception during graceful " +
"attempt to stop partially started component. Please use non suppressed" +
" exception to see original component failure.", se );
e.addSuppressed( lifecycleException );
} }
if ( e instanceof LifecycleException ) if ( e instanceof LifecycleException )
{ {
Expand Down
Expand Up @@ -27,8 +27,18 @@ public class LifecycleException
extends RuntimeException extends RuntimeException
{ {


private static String humanReadableMessage( public LifecycleException( Object instance, LifecycleStatus from, LifecycleStatus to, Throwable cause )
Object instance, LifecycleStatus from, LifecycleStatus to, Throwable cause ) {
super( humanReadableMessage( instance, from, to, cause ), cause );
}

public LifecycleException( String message, Throwable cause )
{
super( message, cause );
}

private static String humanReadableMessage( Object instance, LifecycleStatus from,
LifecycleStatus to, Throwable cause )
{ {
String instanceStr = String.valueOf( instance ); String instanceStr = String.valueOf( instance );
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
Expand Down Expand Up @@ -86,9 +96,4 @@ private static Throwable rootCause( Throwable cause )
} }
return cause; return cause;
} }

public LifecycleException( Object instance, LifecycleStatus from, LifecycleStatus to, Throwable cause )
{
super( humanReadableMessage( instance, from, to, cause ), cause );
}
} }
Expand Up @@ -21,9 +21,12 @@


import org.junit.Test; import org.junit.Test;


import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;


import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
Expand Down Expand Up @@ -464,6 +467,7 @@ public void tryToStopComponentOnStartFailure() throws Throwable
LifeSupport lifeSupport = newLifeSupport(); LifeSupport lifeSupport = newLifeSupport();
Lifecycle component = mock( Lifecycle.class ); Lifecycle component = mock( Lifecycle.class );
doThrow( new RuntimeException( "Start exceptions" ) ).when( component ).start(); doThrow( new RuntimeException( "Start exceptions" ) ).when( component ).start();
doThrow( new RuntimeException( "Stop exceptions" ) ).when( component ).stop();
lifeSupport.add( component ); lifeSupport.add( component );


try try
Expand All @@ -472,19 +476,23 @@ public void tryToStopComponentOnStartFailure() throws Throwable
} }
catch ( Exception e ) catch ( Exception e )
{ {
// expected start failure String message = getExceptionStackTrace( e );
assertThat( message, containsString(
"Exception during graceful attempt to stop partially started component. " +
"Please use non suppressed exception to see original component failure." ) );
} }


assertEquals( LifecycleStatus.STOPPED, lifeSupport.getStatus() ); assertEquals( LifecycleStatus.STOPPED, lifeSupport.getStatus() );
verify( component ).stop(); verify( component ).stop();
} }


@Test @Test
public void tryToShutdownComponentOnStartFailure() throws Throwable public void tryToShutdownComponentOnInitFailure() throws Throwable
{ {
LifeSupport lifeSupport = newLifeSupport(); LifeSupport lifeSupport = newLifeSupport();
Lifecycle component = mock( Lifecycle.class ); Lifecycle component = mock( Lifecycle.class );
doThrow( new RuntimeException( "Init exceptions" ) ).when( component ).init(); doThrow( new RuntimeException( "Init exceptions" ) ).when( component ).init();
doThrow( new RuntimeException( "Shutdown exceptions" ) ).when( component ).shutdown();
lifeSupport.add( component ); lifeSupport.add( component );


try try
Expand All @@ -493,7 +501,10 @@ public void tryToShutdownComponentOnStartFailure() throws Throwable
} }
catch ( Exception e ) catch ( Exception e )
{ {
// expected start failure String message = getExceptionStackTrace( e );
assertThat( message, containsString(
"Exception during graceful attempt to shutdown partially initialized component. " +
"Please use non suppressed exception to see original component failure." ) );
} }


assertEquals( LifecycleStatus.SHUTDOWN, lifeSupport.getStatus() ); assertEquals( LifecycleStatus.SHUTDOWN, lifeSupport.getStatus() );
Expand All @@ -502,6 +513,7 @@ public void tryToShutdownComponentOnStartFailure() throws Throwable


public class LifecycleMock implements Lifecycle public class LifecycleMock implements Lifecycle
{ {

Throwable initThrowable; Throwable initThrowable;
Throwable startThrowable; Throwable startThrowable;
Throwable stopThrowable; Throwable stopThrowable;
Expand Down Expand Up @@ -575,4 +587,11 @@ private LifeSupport newLifeSupport()
{ {
return new LifeSupport(); return new LifeSupport();
} }

private String getExceptionStackTrace( Exception e )
{
StringWriter stringWriter = new StringWriter();
e.printStackTrace( new PrintWriter( stringWriter ) );
return stringWriter.toString();
}
} }

0 comments on commit b6f0120

Please sign in to comment.