Exception handling in drools statefullSession - drools

I'm not sure what is the correct way of handling exceptions in RHS of rules.
I've a statefullSession (drools version 5.5) that keeps firing until halt gets called i.e.
Runnable firingTask = new Runnable() {
public void run() {
ksession.fireUntilHalt();
};
taskExecutor.execute(firingTask);
The problem is that some parts of my code that gets called as a part of consequence section might throw an exception. If that happens no furher activations happen
My question is:
Is there any correct way how application exception should be propagated back to drools? Or is it that any RHS code has to be run inside try/catch block and these exceptions should be propagated as some additional facts into session?

The general strategies for exception handling apply here as well: just consider a consequence as being a static method that is being called due to the fireUntilHalt.
If the exception should or must be handled in the context of the RHS code, you'll have to use a try-catch statement. Otherwise, the exception is propagated and the remainder of the RHS code will not be executed. (This may include the omission of some essential statement such as a modify or insert or retract, which may affect the progress of the session.)
If you catch the exception org.drools.runtime.rule.ConsequenceException in a try around the fireUntilHalt, you can call fireUntilHalt again. The remarks from the previous paragraph apply here as well.
How you log an exception is completely up to you, but inserting Exception objects as facts (and writing rules to reason over them?) seems rather unconventional.

Related

Exception catching in FORM-ENDFORM in subroutine

I am using a subroutine (FORM, ENDFORM) where there is a class-method calling that raises an exception. I am catching the exception from the class-method calling, but how can I pass this exception to where I call the subroutine (PERFORM)?
There's a documentation section for Class-Based Exceptions in Procedures .
If a class-based exception is not handled in a procedure, the system attempts to propagate it to the caller of the procedure. The exceptions that can be propagated from a procedure must be declared in its interface. The caller then knows which exceptions to expect from the procedure. Class-based exceptions are divided into three categories, which determine whether the declaration must be explicit and how it is checked.
In methods of local classes and subroutines, the addition RAISING of the statements METHODS and FORM is used for the declaration
Undeclared exceptions cannot leave a procedure and violate the interface if they are not handled within the procedure. A violation of the interface raises an exception of the predefined class CX_SY_NO_HANDLER, whose exception object contains a reference to the original exception in the attribute PREVIOUS.
See also documentation for FORM RAISING.
START-OF-SELECTION.
TRY.
PERFORM test.
CATCH lcx_some_exception INTO DATA(lx_ex).
ENDTRY.
FORM test RAISING lcx_some_exception.
DATA(lo_test) = NEW lcl_test( ).
lo_test->test( ).
ENDFORM.

What does the Wait operator in Rx.NET do?

In v2.2.5 of the Rx.NET library, there is an operator named Waitthat is defined as so:
public virtual TSource Wait<TSource>(IObservable<TSource> source)
Neither the class library reference on MSDN nor this page mention this operator.
From looking at its implementation, which is a bit too cumbersome to follow, I am guessing it waits for the observable to produce all its elements and returns the last element if the observable had any elements, and if not, it returns the default(TSource). But I am not sure.
If this is correct, then how is it different from LastOrDefaultAsync?
What does it actually do?
The intellisense documentation seems pretty accurate
Waits for the observable sequence to complete and returns the last element of the sequence.
If the sequence terminates with an OnError notification, the exception is thrown.
https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493
So the operator will block the calling thread (YUCK!) until the sequence completes and then yield the last value.
LastOrDefaultAsync in contrast returns an IObservable<T> so is not blocking.
The documentation for the methods are on the Observable class, not the query language implementation.
Waits for the observable sequence to complete and returns the last element of the sequence.
If the sequence terminates with an OnError notification, the exception is throw.
https://github.com/Reactive-Extensions/Rx.NET/blob/v2.2.5/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493
It's essentially a synonym of Last<TSource>().
Wait
Last
The description of Wait provided in the question is not fully correct.
Here are the similarities between Wait and LastOrDefaultAsync:
Both logically wait to receive all the values in the source observable. But as Lee Cambell points out in his answer, Wait blocks the current thread while LastOrDefaultAsync does not.
Here is the summary of differences between Wait and LastOrDefaultAsync:
If there are no elements in the observable sequence, Wait throws an exception; LastOrDefault returns default(TSource).
If an exception occurs during the observation of the observable, Wait reports the exception by invoking observer.OnError but then also throws the exception immediately afterwards; LastOrDefaultAsync only reports the exception by calling observer.OnError on all subscribed observers. However, on error, in both the cases, the observation is stopped.
The XML documentation that comes with the source code (or even with the binary distribution either via NuGet or through the MSI installer) for Rx explains thus:
Waits for the observable sequence to complete and returns the last
element of the sequence. If the sequence terminates with an OnError
notification, the exception is throw.
Exceptions
Throws ArgumentNullException if source is null.
Throws InvalidOperationException if the source sequence is empty.

Exception handling in entire application

I have a few doubts regarding exception handling in iPhone. Here are they:
Suppose I have a chain of methods which are being called one after the other, that is, method A calls method B, which in turn calls method C, which calls method D. Which is the best place to put my try-catch block (is it method A or B or C or D or all of them). Also, I need to display an alert to user that an exception has occured and then, I want to log this exception to my server. So, if I am writing my try - catch block in all of this methods and if an exception occurs in method D; then I think the alert will be displayed 4 times and the web service for logging will also be called 4 times (till control reaches to catch block of method A). So, should I just use #throw; in catch block of method B, C and D and write my logic in catch block of method A (top level method) or should I avoid writing try - catch at all in methods B,C and D.
I need some sort of error code from the exception (because my web service needs parameters error-code and description). Is it possible to convert an exception to error or will I need to hard-code this code?
I had read somewhere about NSSetUncaughtExceptionHandler. And I think, if I can set this handler (in appDidFinishLaunching method of app delegate) and in the handler method, if I show to user some alert and call the web service; then I need not write try - catch block in each of my methods, in each of my classes. Am I right??
If an exception has occured and I have written either a try - catch block or NSSetUncaughtExceptionHandler, then will my app continue running or it will not respond to any of the user events. (I am sure it will handle the crash. What I want to know is whether it will hang)
Someone please enlighten me on this EXCEPTION TOPIC.
0) Avoid exceptions in Cocoa. They are generally non-recoverable. You might catch them for your own error reporting, but it's generally unsafe to assume you can recover from them.
1) If you need to catch, catch it immediately. Don't write your own throws -- instead, convert it to something like an NSError and pass that around. NSError can contain all the information you need to display or send an error code as well as a localized message.
2) You cannot convert an NSException into an NSError (directly) because an NSException does not have all the properties an NSError has - it is a different data representation. For one, an error code is not available. Two, the description is not localized. The best you can do is to create an error code and domain, then use the properties you need from the NSException and store that in an NSError. This could look something like the following:
// error checking omitted
extern NSString* const MONExceptionHandlerDomain;
extern const int MONNSExceptionEncounteredErrorCode;
NSError * NewNSErrorFromException(NSException * exc) {
NSMutableDictionary * info = [NSMutableDictionary dictionary];
[info setValue:exc.name forKey:#"MONExceptionName"];
[info setValue:exc.reason forKey:#"MONExceptionReason"];
[info setValue:exc.callStackReturnAddresses forKey:#"MONExceptionCallStackReturnAddresses"];
[info setValue:exc.callStackSymbols forKey:#"MONExceptionCallStackSymbols"];
[info setValue:exc.userInfo forKey:#"MONExceptionUserInfo"];
return [[NSError alloc] initWithDomain:MONExceptionHandlerDomain code:MONNSExceptionEncounteredErrorCode userInfo:info];
}
#catch (NSException * exc) {
NSError * err = NewNSErrorFromException(exc);
...
}
If the APIs you use throw exceptions you are expected to catch and recover from (e.g. not truly exceptional cases), then yes, you could catch and attempt to continue. Unfortunately, anybody that writes exceptions in Cocoa with the intent that you will catch them probably does not understand the issues well enough to implement a solid unwind implementation (e.g. even if it produces leaks, it's not solid).
3) That's really not the time or place to display an alert. If you install a top level exception handler (via NSSetUncaughtExceptionHandler) - You should simply log a message -- then the exception handler will abort. Your app is in an unstable state -- continuing is worse than aborting. You may want to send these custom messages home, it's best to do so at the next launch of your app.
4) In the majority of cases, your app is in an unstable state and you should not continue. But, to actually answer it for those corner cases: "Yes, you can recover and continue when you catch, but you should only attempt to recover and continue when the throwing API states that recovery is supported. If the problem is beyond your control, and the problem is not exceptional (e.g. file not found), and the vendor really expects you to continue, then I would have to assume that they expect you to continue, even though it really isn't (100% safe).". Do not attempt to recover/continue from within your top level exception handler (the program will abort after it returns). If you want to be very fancy and present that immediately on OSX, another process would be best. If you are calling through a pure C++ interface, then the unwinding is well defined, and the need to catch is necessary - do continue if it is recoverable. Exceptions in C++ can be recoverable and well defined - they are also used quite extensively (including less than exceptional conditions).
(IMO...) Exceptions in ObjC should not have been introduced, and any method that throws from system or third party libraries should be deprecated. They don't unwind well, or in a well defined manner. As well, unwinding flows against normal Cocoa program flow. That means that touching any objc object's memory/relations that was in mutation at the time of the throw and which lies between the throw and the catch is as good as undefined behaviour. Problem is - you have no idea what that memory is (in most cases, and within reasonable maintenance time). C++ exceptions are well defined, and they unwind correctly (e.g. destructors are called) - but trying to continue in an ObjC context is ignoring any consequences of undefined behavior. IMO, they should only exist for ObjC++ (because C++ requires them).
In an ideal world, your ObjC programs and the libraries you use would not use exceptions (at all). Since you use libraries that do throw (including Cocoa), install a top level exception handler only if you need some special information about the error. Where the API mandates that you could expect an exception thrown due to circumstances beyond your control and you are expected to recover, then write a catch but immediately convert that logic to normal program flow (e.g. NSError) - you never need to write your own throw. -[NSArray objectAtIndex: and "object does not respond to selector" are examples of programmer errors - they should not be caught, but the program should be corrected.

Try-catch exception handling practice for iPhone/Objective-C

Apologies if this question has already been answered somewhere else, but I could not find any decisive answer when searching on it:
I'm wondering when try-catch blocks are to be used in objective-c iPhone applications. Apple's "Introduction to the Objective-C Programming Language" state that exceptions are resource intensive and that one should "not use exceptions for general flow-control, or simply to signify errors." From reading a few related questions here I also gather that people are not often using this method in practice.
So I guess the question is: what are the situations when it's appropriate to use try-catch blocks when developing for iPhone/Objective-C and when should they absolutely NOT be used?
For example, I could use them to catch beyond bounds and other exceptions when working with objects in arrays. I have a method which performs are few tasks with objects that are passed on in a number of arrays. The method returns nil if an error has occurred and a try-catch block could help me catch exceptions. However, I could of course simply write little if-tests here and there to ensure that I, for instance, never try to access an index beyond an arrays bounds. What would you do in this situation?
Thanks a lot!
It is only appropriate to use #try/#catch to deal with unrecoverable errors. It is never appropriate to use #throw/#try/#catch to do control-flow like operations.
In particular, it would not be appropriate to use for catching out-of-bounds exceptions unless your goal is to catch them and somehow report the error, then -- typically -- crash or, at the least, warn the user that your app is in an inconsistent state and may lose data.
Behavior of any exception thrown through system framework code is undefined.
Your if-test to do bounds checking is a far more appropriate solution.
#bbum's answer is absolutely correct (and he would know the answer better than most). To elaborate a bit...
In Cocoa, you should generally avoid using exceptions (#try/#catch[/#finally]) for flow control. As you mention, exceptions carry an unusually large cost (compared to run-times such as JVM or the CLR optimized for exception use). Furthermore, most of the Cocoa frameworks are not exception safe. Thus, throwing an exception through Cocoa framework code is dangerous and will likely cause odd, difficult to diagnose, and catastrophic (think possible data loss) bugs in your app.
Instead of using exceptions, Cocoa code uses NSError to signal error conditions that are recoverable within the application. Exceptions are used to signal conditions from which your application cannot recover. Thus a UI component requesting an out-of-bounds position in a model array could be signaled with an error (presented to the user with a reason their request could not be completed) while attempting to access an out-of-bounds position given an index that you think should be valid signals an exceptional condition where you app is in an inconsistent state and should probably die as soon as possible before it can do more damage.
NSParameterAssert, for example signals with an NSException when an assertion fails.
So when should you use exceptions or #try/#catch? If you're using a C/C++ library that makes use of exceptions, you should catch those exceptions before they can get thrown back through Cocoa code. Similarly, if you are serious about consistency of state within your application, you should raise an exception as soon as you detect that your state is inconsistent (and unrecoverable).

Exception, Return, Serializable,

How is (throw Exception) and (return value) implemented in a language such as Java or C#? I want to know the mechanism of how its support is included in a language and not just the usage of try { .... } catch (Exception) {}.
We know when we call a function i.e.
public void doSomething() {
....
....
return;
}
Then on the call is put on the stack and when the method returns the call to doSomething on stack pops out.
What happens in a case where the return statement returns with a value, say return 4;,
the call to doSomething() on the stack pops out, and the next statement on Prog counter got processed? What happened with the returned value? Where did it get saved and how is it utilized?
Similarly in the case of an exception throw, the throw ex; statement finds on the stack the appropriate catch statement, and until it finds it, it keeps popping things out of the stack... How does this mechanism work?
Take a look at this article and see if it helps. It talks about the SEH underpinnings of the .NET (C#) exception system.
EDIT:
If you are asking "How does calling methods with parameters and return values work in something like C# and Java", then look at this article.
At a really low level (what I am thinking you are asking), When you make a call to a method, you push your params onto the stack, then run the function, then pop the return value of the stack into a register and then process off of it, like the following:
Return from method (assembly code)
pop esx - Pop value off stack and store it in the EAX register
jz esx A01h - If the EAX register is zero, jump to this location.
EDIT #2:
In the case of an exception, the managed framework (Java, .NET, etc.) starts to unwind the stack one step at a time looking for a "catch" or "finally" block that can handle the error. It keeps doing this until it finds some block of code that can handle it or it runs out of code and just terminates the program. To understand how all this works at a stack level depends on which managed framework you are talking about, but the first article above combined with this article will give you the deeper view.