Merge pull request #2582 from LukeButtersFunnelback/jetty-9.4.x

Stop creating unnecessary exceptions with MultiException #2580
This commit is contained in:
Greg Wilkins 2018-05-30 11:18:08 +02:00 committed by GitHub
commit eb3461fd84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 29 deletions

View File

@ -26,32 +26,48 @@ import java.util.List;
* Wraps multiple exceptions.
*
* Allows multiple exceptions to be thrown as a single exception.
*
* The MultiException itself should not be thrown instead one of the
* ifExceptionThrow* methods should be called instead.
*/
@SuppressWarnings("serial")
public class MultiException extends Exception
{
private static final String DEFAULT_MESSAGE = "Multiple exceptions";
private List<Throwable> nested;
/* ------------------------------------------------------------ */
public MultiException()
{
super("Multiple exceptions");
// Avoid filling in stack trace information.
super(DEFAULT_MESSAGE, null, false, false);
this.nested = new ArrayList<>();
}
/**
* Create a MultiException which may be thrown.
*
* @param nested The nested exceptions which will be suppressed by this
* exception.
*/
private MultiException(List<Throwable> nested) {
super(DEFAULT_MESSAGE);
this.nested = new ArrayList<>(nested);
if(nested.size() > 0) {
initCause(nested.get(0));
}
for(Throwable t : nested) {
this.addSuppressed(t);
}
}
/* ------------------------------------------------------------ */
public void add(Throwable e)
{
if (e==null)
throw new IllegalArgumentException();
if(nested == null)
{
initCause(e);
nested = new ArrayList<>();
}
else
addSuppressed(e);
if (e instanceof MultiException)
{
MultiException me = (MultiException)e;
@ -105,7 +121,7 @@ public class MultiException extends Exception
if (th instanceof Exception)
throw (Exception)th;
default:
throw this;
throw new MultiException(nested);
}
}
@ -137,7 +153,7 @@ public class MultiException extends Exception
else
throw new RuntimeException(th);
default:
throw new RuntimeException(this);
throw new RuntimeException(new MultiException(nested));
}
}
@ -155,7 +171,9 @@ public class MultiException extends Exception
return;
if (nested.size()>0)
throw this;
{
throw new MultiException(nested);
}
}
/* ------------------------------------------------------------ */

View File

@ -21,10 +21,11 @@ package org.eclipse.jetty.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
public class MultiExceptionTest
{
@ -37,6 +38,8 @@ public class MultiExceptionTest
me.ifExceptionThrow();
me.ifExceptionThrowMulti();
me.ifExceptionThrowRuntime();
assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length);
}
@Test
@ -65,7 +68,7 @@ public class MultiExceptionTest
}
catch(MultiException e)
{
assertTrue(e==me);
assertTrue(e instanceof MultiException);
}
try
@ -91,19 +94,26 @@ public class MultiExceptionTest
{
assertTrue(run==e);
}
assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length);
}
@Test
public void testTwo() throws Exception
{
private MultiException multiExceptionWithTwo() {
MultiException me = new MultiException();
IOException io = new IOException("one");
RuntimeException run = new RuntimeException("one");
me.add(io);
me.add(run);
assertEquals(2,me.size());
assertEquals("Stack trace should not be filled out", 0, me.getStackTrace().length);
return me;
}
@Test
public void testTwo() throws Exception
{
MultiException me = multiExceptionWithTwo();
try
{
me.ifExceptionThrow();
@ -111,9 +121,11 @@ public class MultiExceptionTest
}
catch(MultiException e)
{
assertTrue(e==me);
assertTrue(e instanceof MultiException);
assertTrue(e.getStackTrace().length > 0);
}
me = multiExceptionWithTwo();
try
{
me.ifExceptionThrowMulti();
@ -121,9 +133,11 @@ public class MultiExceptionTest
}
catch(MultiException e)
{
assertTrue(e==me);
assertTrue(e instanceof MultiException);
assertTrue(e.getStackTrace().length > 0);
}
me = multiExceptionWithTwo();
try
{
me.ifExceptionThrowRuntime();
@ -131,9 +145,11 @@ public class MultiExceptionTest
}
catch(RuntimeException e)
{
assertTrue(e.getCause()==me);
assertTrue(e.getCause() instanceof MultiException);
assertTrue(e.getStackTrace().length > 0);
}
RuntimeException run = new RuntimeException("one");
me = new MultiException();
me.add(run);
me.add(run);
@ -145,7 +161,9 @@ public class MultiExceptionTest
}
catch(RuntimeException e)
{
assertTrue(e.getCause()==me);
assertTrue(e.getCause() instanceof MultiException);
Assert.assertEquals(e.getCause().getCause(), run);
assertTrue(e.getStackTrace().length > 0);
}
}
@ -158,7 +176,13 @@ public class MultiExceptionTest
me.add(io);
me.add(run);
assertEquals(2,me.size());
assertEquals(io,me.getCause());
try {
me.ifExceptionThrow();
} catch (MultiException e) {
assertEquals(io,e.getCause());
assertEquals(2,e.size());
}
}
}