How can I stop a Gradle build after detecting a problem? I can use an assert, throw an exception, do a System.exit (bad idea), or use a dedicated function in Gradle (but I could not find one). What is the best way for Gradle (and why?).
I usually throw the relevant exception from the org.gradle.api package, for example InvalidUserDataException for when someone has entered something invalid, or GradleScriptException for more general errors.
If you want to stop the current task or action, and move on to the next, you can also throw a StopActionException
If you want to stop the build, throw:
throw new GradleException('error occurred')
or throw the subclasses for the above exception. Some of the subclass exceptions actually only fail the current task but continue with the build.
There is currently no dedicated method, although there have been discussions to add one.
The recommended way to stop a Gradle build is to throw an exception. Since Groovy doesn't have checked exceptions, and Gradle by default does not print the exception type, it's not that critical which exception is thrown. In build scripts, GradleException is often used, but a Groovy assertion also seems reasonable (depending on the circumstances and audience). What's important is to provide a clear message. Adding a cause (if available) helps for debugging (--stacktrace).
Gradle provides dedicated exception types StopExecutionException/StopActionException for stopping the current task/task action but continuing the build.
Another option if you don't have any desire to be able to catch the exception later on is to call the ant fail task. It's slightly easier to read in my opinion and you can give a nice message to the user without use of --stacktrace.
task (tarball, dependsOn: warAdmin) << {
ant.fail('The sky is falling!!')
}
Gives you a message like:
* What went wrong:
Execution failed for task ':tarball'.
> The sky is falling!!
Probably you can catch this (perhaps it throws ant's BuildException?) but if that's a goal then I wouldn't use ant.fail. I'd just make it easy to see what exception to catch by throwing standard gradle exception as tim_yates suggested.
Throwing a simple GradleException works in stopping the build script. This works great for
checking required environment setup.
GradleException('your message, why the script is stopped.')
Example:
if(null == System.getenv()['GRADLE_USER_HOME']) {
throw new GradleException('Required GRADLE_USER_HOME environment variable not set.')
}
Here is a code fragment that tries to emulate how the Gradle javac task throws errors:
task myCommand(type:Exec) {
... normal task setup ....
ignoreExitValue true
standardOutput = new ByteArrayOutputStream()
ext.output = { standardOutput.toString() }
doLast {
if (execResult.exitValue) {
logger.error(output())
throw new TaskExecutionException( it,
new Exception( "Command '${commandLine.join(' ')}' failed; "
+ "see task output for details." )
)
}
}
}
When the command returns 0 there is no output. Any other value will print the standardOutput and halt the build.
NOTE: If your command writes to errorOutput as well, you may need to include that in the error log.
Related
Alright, this is probably the biggest program i have ever written. I use task in it once so that on first run it will search all available files and folders for certain things. Everything works...well, did work. Now when i start the program after adding a few more features in. It is throwing stack overflow errors on things that never had a problem before.
My first one was right in the begging it threw on a simple return of,
return System.Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)
i changed it to just return
public string BaseUpdaterPath { get { return "C:\\Users\\Public\\Documents"; } }
and it started working again.
it got alittle further into the program untill it runs a check to see if a specific path exists.
if (File.Exists(pathINI))
pathini is defined earlier as
string pathINI = (BaseProductPath + "\\" + Name + ".ini");
and baseproduct is
public string BaseProductPath { get { return BaseUpdaterPath + "\\" + Name; } }
these are things that should not be breaking. My error is this
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
with more investigation turns into this
Source Evaluation of method System.Exception.get_Source requires calling method System.Reflection.RuntimeMethodInfo.CreateDelegate, which cannot be called in this context. string
I can only imagine this has something to do with threading and the initial search that I am doing if this is the programs first run time.
If i can provide anymore information that i may have overlooked in my details i would be happy to provide it. I have not seen errors like this before that don't really give you much to go off of.
I may just end up throwing up a splash screen during that initial search if it's going to keep causing problems like this and have the rest of the program wait on that task.
UPDATE
I just stepped through my program starting at different steps and i was able to get past that check it kept kicking it out at. Then i got to a different if(foo == bar) and visual studio did this strange thing where it popped up a little loading window and said evaluating BAR then killed the program with
has exited with code -2147023895 (0x800703e9).
wtf is going on lmao
Another update incase anyone runs into this. I have a product preselected when i started up the programming, i wrote checks in to accommodate this however....it blocked me from being able to see what is really happening.
I disabled some code and let the thing run and after a while i found this little bastard popping up on the console
Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
Exception thrown: 'System.IO.PathTooLongException' in mscorlib.dll
now i gotta track that down to wherever the hell it's throwing 5000 times and i should be good to go.
Update again if anyone cares.
I found out that even i caught and threw the exception away it was still getting stackoverflow in windows.old because they have tons of folders and files and i was running out of memory. My solution at this point is during the recursive file check to just discard anyfolder in windows.old. Cant think of a better way.
THE EPIC CONCLUSION...I AM A DUMBASS
i was having two properties check eachother
public bool IsInstalled { get
{
if (DefaultInstalledpath != null || DefaultInstalledpath != "Not Installed")
{
return true;
}
else
{
return false;
}
}
public string DefaultInstalledpath
{
get
{
else if(!File.Exists(pathTXT) && IsInstalled == true)
{
return "Discovering! Please Wait...";
}
.........
i don't wanna talk about the rabbit hole i just fell down
I got a scenario
#walk
Given a man is standing
When he starts moving
Then he covers 5 meters
[BeforeScenario("walk")]
public void BeforeWalkScenario()
{
SetEnvironmentForWalk();
}
[AfterScenario("walk")]
public void AfetrWalkScenario()
{
ClearWalk();
}
In my test, execution is failing on 'When' statement and error is produced. Also, since I have a AfterScenario as well, it also get's executed after the error.
Unfortunately, my test is again failing in AfterScenario block. Due to this, in test report only AfterScenario error is noted and reported. How can I make sure my testresult report also shows the reason for failure on When statement.
Help would be appreciated. New to BDD. Thanks!
In ScenarioContext.TestError you get the last thrown exception from your bindings.
You can check this in your hooks.
See http://www.specflow.org/documentation/ScenarioContext/
I am trying to create a cronjob in cq using a time interval
I see on the link https://sling.apache.org/documentation/bundles/scheduler-service-commons-scheduler.html I could make job1 run and it will work. But I have a questions on the code.
In the below code
Why is job1.run() invoked in a catch block? Can we not add it to the try block?
Can I replace the catch block instead of job1.run() using thread using start and can I add in try block or must it be in the catch block?
Thread newThread = new Thread(job1);
newThread.start();
I see the cronjob code in the above link
protected void activate(ComponentContext componentContext) throws Exception {
//case 1: with addJob() method: executes the job every minute
String schedulingExpression = "0 * * * * ?";
String jobName1 = "case1";
Map<String, Serializable> config1 = new HashMap<String, Serializable>();
boolean canRunConcurrently = true;
final Runnable job1 = new Runnable() {
public void run() {
log.info("Executing job1");
}
};
try {
this.scheduler.addJob(jobName1, job1, config1, schedulingExpression, canRunConcurrently);
} catch (Exception e) {
job1.run();
}
}
According to the Javadoc, addJob, addPeriodicJob and fireJobAt will throw an Exception if the job cannot be added. The docs do not suggest anything regarding the cause of such failures.
The snippet on the Apache Sling Scheduler documentation page that you quoted in your question catches and ignores these exceptions.
Looking at the implementation provided, job1 is just a regular runnable so executing the run method manually in the catch block does not affect the Scheduler at all.
What it seems to be doing is attempt to add the job and in case of failure, silently ignore it and run it manually so that it prints "Executing job1"
There are at least two serious problems with this approach:
The code ignores the fact that something went wrong while adding the job and pretends this never happens (no logging, nothing)
It runs the job manually giving you the impression that it has been scheduled and just ran for the first time.
As to why it's happening? I have no idea. It's just silly and It's certainly not something I'd like to see in actual, non-tutorial code.
The API using such a generic exception to signal failure is also quite unfortunate.
Coincidentally, Sling 7 deprecates addJob, addPeriodicJob and fireJobAt and replaces them all with schedule. The schedule method returns a boolean so it doesn't give any more information about what exactly happened but it doesn't require you to use ugly try catch blocks.
If you're unable to use the latest version of Sling, make sure to use a logger and log the exceptions. Running your jobs manually, whatever they are, probably won't make much sense but that's something you need to decide.
We have a number of sections of code in the format:
try
{
// code
}
catch(std::exception &e)
{
// log exception
}
catch(...)
{
// log unknown exception.
}
Every so often, the unknown exception code triggers, and logs an unknown exception.
I always thought that all exceptions were meant to derive from std::exception, and thus catching std::exception would catch all exceptions.
Is there some other exception that I should be catching?
If my code ends up in the unknown exception handler, is there any way that I can find out what exception was actually caught?
edit
We managed to locate the cause of the problem- despite saying that they had, the customer had not installed .NET 3.5, which our code depends on, and the system fell over when trying to use the XML parser.
Is there some other exception that I should be catching?
This depends on your code. Libraries you call can throw exceptions not derived from std::exception, examples are MFC's CException or Microsoft's _com_error. Also, an access violation might be catched by catch(...), which is the reason why I would not use catch(...) in my code - it's just to broad for me.
2.If my code ends up in the unknown exception handler, is there any way that I can find out what exception was actually caught?
You can run your code in the debugger and configure the debugger to break your program when the exception is thrown (first chance). Then you know exactly which line of code triggers the exception and should be able to see what exactly is thrown.
I am writing a program to read all files from an array.
Suppose in between if any file is corrupt or any reason it will stop the execution in between and throw an exception
I want to let the code running till end and at last it logged the error files instead of throwing exception?
try{
doSomethingThatMayRaiseAndException();
}
catch (Exception e){
NotifyTheUserThatSomethingBadJustHappened();
}
Exception here is the base class for exceptions, you may need to use a more specific one if you want to provide the user with details. But right now, what you need to learn is how to deal with exceptions. You can use the link provided by Oded, it is a good start. Then note what is the raised exception you need to handle, and handle it.