HierarchicalMicroScheduler no longer attempts to wrap exceptions
-- This behavior, which isn't obviously valuable at all, continued to grab and rethrow exceptions in the HMS that, if run without NT, would show up as more meaningful errors. Now HMS simply checks whether the throwable it received on error was a RuntimeException. If so, it is stored and rethrow without wrapping later. If it isn't, only in this case is the exception wrapped in a ReviewedStingException. -- Added a QC walker ErrorThrowingWalker that will throw a UserException, ReviewedStingException, and NullPointerException from map as specified on the command line -- Added IT that ensures that all three types are thrown properly (i.e., you catch a NullPointerException when you ask for one to be thrown) with and without threading enabled. -- I believe this will finally put to rest all of these annoying HMS captures.
This commit is contained in:
parent
ab288354e9
commit
ff26f2bf68
|
|
@ -47,7 +47,7 @@ public class HierarchicalMicroScheduler extends MicroScheduler implements Hierar
|
|||
/**
|
||||
* An exception that's occurred in this traversal. If null, no exception has occurred.
|
||||
*/
|
||||
private Throwable error = null;
|
||||
private RuntimeException error = null;
|
||||
|
||||
/**
|
||||
* Queue of incoming shards.
|
||||
|
|
@ -345,22 +345,22 @@ public class HierarchicalMicroScheduler extends MicroScheduler implements Hierar
|
|||
return error != null;
|
||||
}
|
||||
|
||||
private synchronized StingException getTraversalError() {
|
||||
private synchronized RuntimeException getTraversalError() {
|
||||
if(!hasTraversalErrorOccurred())
|
||||
throw new ReviewedStingException("User has attempted to retrieve a traversal error when none exists");
|
||||
|
||||
// If the error is already a StingException, pass it along as is. Otherwise, wrap it.
|
||||
if(error instanceof StingException)
|
||||
return (StingException)error;
|
||||
else
|
||||
return new ReviewedStingException("An error occurred during the traversal.",error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows other threads to notify of an error during traversal.
|
||||
*/
|
||||
protected synchronized void notifyOfTraversalError(Throwable error) {
|
||||
this.error = error;
|
||||
// If the error is already a Runtime, pass it along as is. Otherwise, wrap it.
|
||||
if (error instanceof RuntimeException)
|
||||
this.error = (RuntimeException)error;
|
||||
else
|
||||
this.error = new ReviewedStingException("An error occurred during the traversal.", error);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2011, The Broad Institute
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.broadinstitute.sting.gatk.walkers.qc;
|
||||
|
||||
import org.broadinstitute.sting.commandline.Input;
|
||||
import org.broadinstitute.sting.gatk.contexts.AlignmentContext;
|
||||
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
|
||||
import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker;
|
||||
import org.broadinstitute.sting.gatk.walkers.RodWalker;
|
||||
import org.broadinstitute.sting.gatk.walkers.TreeReducible;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
||||
/**
|
||||
* a walker that simply throws errors. Allows us to test that the engine is behaving as expected with error handling
|
||||
*/
|
||||
public class ErrorThrowingWalker extends RodWalker<Integer,Integer> implements TreeReducible<Integer> {
|
||||
@Input(fullName="exception", shortName = "E", doc="Java class of exception to throw", required=true)
|
||||
public String exceptionToThrow;
|
||||
|
||||
//
|
||||
// Template code to allow us to build the walker, doesn't actually do anything
|
||||
//
|
||||
@Override
|
||||
public Integer map(RefMetaDataTracker tracker, ReferenceContext ref, AlignmentContext context) {
|
||||
if ( exceptionToThrow.equals("UserException") ) {
|
||||
throw new UserException("UserException");
|
||||
} else if ( exceptionToThrow.equals("NullPointerException") ) {
|
||||
throw new NullPointerException();
|
||||
} else if ( exceptionToThrow.equals("ReviewedStingException") ) {
|
||||
throw new ReviewedStingException("ReviewedStingException");
|
||||
} else {
|
||||
throw new UserException.BadArgumentValue("exception", "exception isn't a recognized value " + exceptionToThrow);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer reduceInit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer reduce(Integer value, Integer sum) {
|
||||
return value + sum;
|
||||
}
|
||||
|
||||
public Integer treeReduce(final Integer lhs, final Integer rhs) {
|
||||
return lhs + rhs;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,9 +25,13 @@
|
|||
package org.broadinstitute.sting.gatk;
|
||||
|
||||
import org.broadinstitute.sting.WalkerTest;
|
||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -73,4 +77,45 @@ public class EngineFeaturesIntegrationTest extends WalkerTest {
|
|||
@Test() private void testMissingInterval() {
|
||||
testMissingFile("missing interval", "-T UnifiedGenotyper -L missing.interval_list -I " + b37GoodBAM);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
//
|
||||
// Test that our exceptions are coming back as we expect
|
||||
//
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
private class EngineErrorHandlingTestProvider extends TestDataProvider {
|
||||
Class expectedException;
|
||||
boolean multiThreaded;
|
||||
|
||||
public EngineErrorHandlingTestProvider(Class exceptedException, final boolean multiThreaded) {
|
||||
super(EngineErrorHandlingTestProvider.class);
|
||||
this.expectedException = exceptedException;
|
||||
this.multiThreaded = multiThreaded;
|
||||
setName(String.format("Engine error handling: expected %s, is-multithreaded %b", exceptedException, multiThreaded));
|
||||
}
|
||||
}
|
||||
|
||||
@DataProvider(name = "EngineErrorHandlingTestProvider")
|
||||
public Object[][] makeEngineErrorHandlingTestProvider() {
|
||||
for ( final boolean multiThreaded : Arrays.asList(true, false)) {
|
||||
new EngineErrorHandlingTestProvider(NullPointerException.class, multiThreaded);
|
||||
new EngineErrorHandlingTestProvider(UserException.class, multiThreaded);
|
||||
new EngineErrorHandlingTestProvider(ReviewedStingException.class, multiThreaded);
|
||||
}
|
||||
|
||||
return EngineErrorHandlingTestProvider.getTests(EngineErrorHandlingTestProvider.class);
|
||||
}
|
||||
|
||||
//
|
||||
// Loop over errors to throw, make sure they are the errors we get back from the engine, regardless of NT type
|
||||
//
|
||||
@Test(dataProvider = "EngineErrorHandlingTestProvider")
|
||||
public void testEngineErrorHandlingTestProvider(EngineErrorHandlingTestProvider cfg) {
|
||||
final String root = "-T ErrorThrowing -R " + b37KGReference;
|
||||
final String args = root + (cfg.multiThreaded ? " -nt 2" : "") + " -E " + cfg.expectedException.getSimpleName();
|
||||
WalkerTestSpec spec = new WalkerTestSpec(args, 0, cfg.expectedException);
|
||||
executeTest(cfg.toString(), spec);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue