Exit question

Hello all,

I am looking for the best practice to solve the following problem:

  • A service S1:
    1. Sequence success (main)
    1.1 Sequence failure (try)
    1.1.1 Invoke S2
    1.2 Sequence done (catch)
    1.2.1 Catch threatment (getLastError etc…)

  • A service S2:
    2. Sequence success (main)
    2.1 Sequence failure (try)
    2.1.1 Business threatment (may lead to generate some exceptions)
    2.2 Sequence done (catch)
    2.2.1 Invoke getLastError
    2.2.2 Invoke S3

My question concerns the service S3. In this service I would like to execute some log actions (for instance publish a Log event) and generates an exception which allows me to return in the catch of the service S1 (1.2).
But I did not find any solution yet, if I’m calling an Exit statement in S3, this exception will not be thrown to S1.
The only way would be to add a 2.2.3 with an Exit statement (and to remove it from S3) but no way to include it in S3…

If someone finds a miracle, I’d be grateful :slight_smile:

Hi Teiva,

did you try “Exit from $flow and signal failure”?

This should propagate the exception to the calling service.

Regards,
Holger

Hi,

No Holger, the error is not thrown to the service S1.
So far the only thing I’ve found is to set up S3 as a Java service and to use InvokeState API with:

InvokeState.getCurrentState().getFlowState().getParent().getParent().setError(myException)

But don’t ask me why, this piece of code only works at debugging level, not at runtime (the getParents returns a FlowState object only in debug mode).

Hi Olivier,

another option might be the service pub.flow:throwExceptionForRetry, but I am not quite sure.

Regards,
Holger

Nope, it doesn’t work…

I don’t understand why the FlowState API would be different at run and design time :cry:

First, I am not sure for what circumstance, you are creating like this. As per best practice, you should not use exception handling in child service. As per your example, S3 service should be called under S1. Also, Main service should not fail at anytime because of child service.

See S3 not as a business service but as an utility service to log messages and to throw exception.

I want to create a pattern for child services (such as S2, services called by a top service) and to manage the catch sequence always like this:

  • getLastError
  • S3 (also called in my framework sendException)

And sorry rskarthikeyan but I stronly disagree with

(but thanks for the help though).

If you do not catch exception sent by child services (let’s say without any sequences to catch potential exceptions), it means that it is your top service that will catch the exception.
For me this is not a good practice in terms of logging. Indeed, if your child service catch potential errors, you will me able to concatenate the runtime issue with a proper message depending on the below service execution such as:
“Error while mapping … format to … canonical: %lastError/error%” or “Error while calling web services: %lastError/error%”.
Or you would need to set a branch in the catch of your top level service but it is harder to implement (in my opinion still)

Jamin, from S3 you use Exist from parent and throw some message on failure, it should reach to S1 catch block. Please give a try and let me know.

Thanks,

Thanks for your help but it is the same proposition than just before so I’m going to give you the same reply: it does not work.

Hi Oliver,
You would not be able to achieve the desired scenario with only exit statement, you would need to make use of vaariables as well.
Set the validateStatus variable in service S3 as false, check in service S2 the value of validateStatus and depending upon that variable exit the flow and signal failure from S2.
This should invoke catch block of Service S1.
Give it a try.

If one day someone understand my requirement and find this thread, please note the solution is to create S3 as a Java service, and to put this:

Values v = new Values();
v.setValue("from", "$flow");
v.setValue("signal", "failure");
v.setValue("failure-message", "sendException: " + IDataUtil.getString(pipeline.getCursor(), "msg"));
FlowExit exit = new FlowExit(v);
InvokeState.getCurrentState().getFlowState().setExit(exit);

This way, the error is thrown though S1. It is the only possible solution (InvokeState.getCurrentState().getFlowState().getParent().setError(error) works only in debug mode).

Have fun.

Olivier,

Thanks for the update and posting back to this thread. It will in deed helps other!

HTH,
RMG

Olivier – Thanks for your great efforts, updating the thread with resolution which absolutely useful to others.

Thanks,

Maybe a bit late but if you call S3 outside of the main sequence (branch over a variable defined on the Catch sequence, so it will only be called on error case) you can call the pub.flow:throwExceptionForRetry service.

It should work :slight_smile: