Handle only certain exceptions in Camel sub-route - exception

Thanks to this question I know that I need to specify errorHandler(noErrorHandler()) in a sub-route in order for exceptions to be propagated to the parent route in Camel. However I would like to handle some exceptions in the sub-route but propagate the rest to the parent.
For example:
from("direct:top")
.onException(Exception.class)
.log("Top-level: ${exception}")
.continued(true)
.end()
.to("mock:start")
.to("direct:sub1")
.to("direct:sub2")
.end();
from("direct:sub1")
.errorHandler(noErrorHandler())
.to("mock:sub1")
.throwException(new IllegalArgumentException("test"));
from("direct:sub2")
.onException(IllegalArgumentException.class)
.log("Sub2: ${exception}")
.continued(true)
.end()
// but I want all other exceptions to be propagated to the top handler
.to("mock:sub2")
.throwException(new IllegalArgumentException("test"))
.throwException(new NullPointerException("test"));
sub1 works as expected, but I'd like sub2 to locally handle and log the IllegalArgumentException and allow the NullPointerException to bubble up to the parent. However, my log output looks like this:
10:35:28.048 [main] INFO route1 - Top-level: java.lang.IllegalArgumentException: test
10:35:28.049 [main] INFO route3 - Sub2: java.lang.IllegalArgumentException: test
10:35:28.056 [main] ERROR DefaultErrorHandler - Failed delivery for (MessageId: xxxx on ExchangeId: xxx). Exhausted after delivery attempt: 1 caught: java.lang.NullPointerException: test
If I add errorHandler(noErrorHandler()) to sub2 the IllegalArgumentException is propagated to the parent (which I don't want) and the NullPointerException isn't logged at all. Is there any way to achieve my desired behaviour?

When you throw an exception the exception is cought and route ends immediately, so the second exception can't be thrown. If you want to throw the second exception only if the first one occurs you should throw it from onException block (before .end)

Related

Cannot use transfer or send on solidity

I use Ganache, truffle.
I get the following error:
Error: [ethjs-query] while formatting outputs from RPC '{"value":{"code":-32603,"data":{"message":"VM Exception while processing transaction
I have located the problematic piece of code:
bool sent = _sellerAddress.send(_price);
Now, I get the price via the user interaction, and when the price is 0, then the error is not thrown,
unfortunately in the classic case when the _price is no zero, the exception is thrown.
Any suggestions?

File component's [consumer.]bridgeErrorHandler in conjunction with startingDirectoryMustExist

I have a route (with Camel 2.23.1) like:
from("file://not.existing.dir?autoCreate=false&startingDirectoryMustExist=true&consumer.bridgeErrorHandler=true")
.onException(Exception.class)
.handled(true)
.log(LoggingLevel.ERROR, "...exception text...")
.end()
.log(LoggingLevel.INFO, "...process text...")
...
(I tried it with just &bridgeErrorHandler, too, since according to the latest doc the consumer. prefix seems to be not necessary any longer.)
According to the doc of startingDirectoryMustExist:
| startingDirectoryMustExist | [...] Will thrown an exception if the directory doesn’t exist. |
the following exception is thrown:
org.apache.camel.FailedToCreateRouteException: Failed to create route route1:
Route(route1)[[From[file://not.existing.dir?autoCreate=false...
because of Starting directory does not exist: not.existing.dir
...
but, despite of the doc and the description of [consumer.]bridgeErrorHandler it's propagated to the caller, i.e neither "exception text" nor "process text" are printed.
There is a unit test FileConsumerBridgeRouteExceptionHandlerTest that covers consumer.bridgeErrorHandler, so I think this works basically. Can it be that [consumer.]bridgeErrorHandler doesn't work in conjunction with the exception thrown by startingDirectoryMustExist?
Do I have to write my own [consumer.]exceptionHandler as mentioned in this answer to "Camel - Stop route when the consuming directory not exists"?
There also a post on the mailing list from 2014 that reports similar behaviour with startingDirectoryMustExist and consumer.bridgeErrorHandler.
UPDATE
After TRACEing and debugging through the code I found that the exception is propagated as follows:
FileEndpoint.createConsumer()
throw new FileNotFoundException(...);
--> RouteService.warmUp()
throw new FailedToCreateRouteException(...)
--> DefaultCamelContext.doStart()
(re)throw e
--> ServiceSupport.start()
(re)throw e
I couldn't find any point where bridgeErrorHandler comes into play.
Setting breakpoints on BridgeExceptionHandlerToErrorHandler's constructor and all of its handleException() methods doesn't stop at any of them.
Am I still missing something?
You should use the directoryMustExist option instead, then you can have the error during polling, which is where the bridge error handler can be triggered. The startingDirectoryMustExist option is checked during creating the consumer and therefore before the polling and where the bridge error handler operates.
See also the JIRA ticket: https://issues.apache.org/jira/browse/CAMEL-13174

catching classes that do not inherit from BaseException is not allowed

I'm making a custom plugin to query a database for user info to aide customer support. My backend is slack.
Everytime I start the bot command I'm greeted with:
Computer says nooo. See logs for details:
catching classes that do not inherit from BaseException is not allowed
I'm not sure if this is warning me that I'm attempting to catch an exception that isn't a BaseClass in my code or if an unknown exception was raised and caught elsewhere outside of my plugin.
To debug I tried:
try:
do_the_thing()
except (TypeError, ValueError) as e:
return('Something went wrong.')
I also tried:
try:
do_the_thing()
except Exception as e:
return('Something went wrong.')
And I still get the errbot admonition. Note that the command still runs and does the right thing where there is no exception raised by do_the_thing().
It means that:
Somewhere in your code you have an except ... statement where the exception ... (or one of the exceptions in the sequence ...) is not a subclass of BaseException, and
An exception is being thrown that is caught by that except ... statement.
The TypeError can be raised only when an exception is actually thrown because the names you give to except ... must be evaluated for their current values at that time; just because TypeError referenced a particular class at one point in the program's execution doesn't mean it won't be changed later to reference another object (though that would be admittedly perverse).
The Python interpreter should be giving you a full traceback of the exception; the first thing you need to do is find this. It could be occurring in one of two situations. (This is for single-threaded programs; I'm assuming your program is not multithreaded.)
During the execution of your program, in which case the program will be terminated by the exception, or
During finalization of objects (in their __del__(self) functions) in which case the error will be printed to stderr.
In both cases there should be a stack trace, not just the error message; I've confirmed that at least on Python ≥3.4 a stack trace is printed out for case 2.
You then need to follow this stack trace to see where the problem lies. Remember that the names you give to except ... are variables (even things like TypeError) that can be reassigned, so that you could conceivably be dealing with a (perverse) situation like:
TypeError = False
try:
...
except TypeError:
...
But more likely it will be something obvious such as:
class MyException: # Doesn't inherit from Exception
...
try:
...
except MyException:
...
There is one special case you need to be aware of: if you are seeing messages to stderr (case "2. During finalization," above) printed out as your program exits that means that the exception was thrown during cleanup as the interpreter shuts down, where random variables throughout the program may have already been set to None as part of the cleanup process. But in this case your program should still exit successfully.

Wrapping an exception within another exception in OCaml

Can I make an exception which contains another exception in its constructor? I want to throw an exception about what exception happened lower down.
Yes, like this:
exception Foo
exception Bar of exn
Might get problems with printing.
Fatal error: exception Bar(_)

Fetching Error Code in mule

I want to create a custom exception message in case exception is thrown by my mule service. In order to do that, i want to separately capture mule generated ErrorCode. Is there any property using which i can get that value? I tried using #[org.mule.config.ExceptionHelper.getErrorCode(Exception.class)]" but this returned -1 as a value instead of the actual exception code.
What method can i use to fetch ErrorCode?
You are supposed to pass the class of the current exception, ie:
#[org.mule.config.ExceptionHelper.getErrorCode(exception.class)]"
exception is the current exception while Exception is the java.lang.Exception class for which there is no error code associated.