- The normal behaviour is that JobScheduler handles exit codes <> 0 as an error.
- Depending on the error handling, the order moves to the error state, will be suspended or will enter a setback interval.
- You can modify this behaviour by implementing some post-processing:
- For the following example job chain the post-processing is configured as a CDATA element for better readability.
- You could also provide a file with a post-processing script to organise some general use of error handling by including the file to multiple job chains.
- There are two possible approaches:
- the first handles each exit code individually and
- the second is more generic.
- You switch between the examples by changing the exit code of the first step. If the exit code is 0, then the more generic example will be executed.
- To make this example work for your environment you can download the configuration files and add them to a folder in the ./config/live directory.
First Example
Job: job_with_exit_code
<job order="yes">
<script language="shell"><![CDATA[
rem this is a shell script ending with an exit code
exit 0
]]></script>
<monitor name="exitCodeDispatcher"
ordering="0">
<script language="javax.script:ECMAscript"><![CDATA[
function spooler_task_after() {
var exitCode = spooler_task.exit_code();
var order = spooler_task.order();
spooler_log.info ( "Exit Code is: " + exitCode );
result = true;
switch ( exitCode ) {
case 0: // example to proceed the job chain at another node
spooler_log.info( "proceeding with next step" );
break;
case 1: // example to proceed the job chain at another node
order.set_state( "300" );
break;
case 2: // example to end with an end state
order.set_state( "success:2" );
break;
default: // Other exit codes are handled as an error
// spooler_log.info( "Exit Code of " + order.job_chain() + "/" + order.id() + " in node " + order.job_chain_node().state() + " was " + exitCode );
result = false;
break;
}
// If you want to avoid messages like
// 2011-08-04 10:13:14.531 [ERROR] (Task sample/job_with_exit_code:1001447) SCHEDULER-280 Process terminated with exit code 1 (0x1)
// spooler_task.set_exit_code( 0 );
return result;
}
// This could be done in a more generic way
// See example in step job_with_exit_code_generic
]]></script>
</monitor>
<run_time/>
</job>
Second Example
Job: job_with_exit_code_generic
<job order="yes">
<params/>
<script language="shell"><![CDATA[
rem another example
exit 98
]]></script>
<monitor name="exitCodeDispatcherGeneric"
ordering="0">
<script language="javax.script:ECMAscript"><![CDATA[
function spooler_task_after() {
// You define a node with exit.<exitCode> for each possible exitCode
// If node is not defined, a default will be used
var exitCode = spooler_task.exit_code();
var order = spooler_task.order();
if ( exitCode != 0 ) {
newState = "exit." + exitCode;
try { //Checking, whether node is defined in job chain configuration
order.job_chain().node( newState )
} catch (e) {
order.set_state( "exit.default" );
}
order.set_state( "exit." + exitCode );
}
return true;
}
]]></script>
</monitor>
<run_time/>
</job>
Job and Job Chain for both Examples
Job: job_sample
<job order="yes"
title="Just an Example Job">
<script language="shell"><![CDATA[
echo "here comes an example"
]]></script>
<run_time/>
</job>
Job Chain: job_chain_exit_code_dispatcher
<job_chain orders_recoverable="yes"
title="Example for a job chain with handling exit codes">
<job_chain_node state="firstStep"
job="job_with_exit_code"
next_state="secondStep"
error_state="error"/>
<job_chain_node state="secondStep"
job="job_with_exit_code_generic"
next_state="200"
error_state="error"/>
<job_chain_node state="200"
error_state="error"
job="job_sample"
next_state="300"/>
<job_chain_node state="300"
error_state="error"
job="job_sample"
next_state="400"/>
<job_chain_node state="400"
error_state="error"
job="job_sample"
next_state="success"/>
<job_chain_node state="success"/>
<job_chain_node state="success:2"/>
<job_chain_node state="error"/>
<job_chain_node state="exit.99"/>
<job_chain_node state="exit.default"/>
</job_chain>