I have a Camel route in which I'm trying to process a file and then try to insert a row to a database based on whether the file processing was successful. I just add a property "processed" and set it to true if the processing was successful in the bean I called. Since I'm checking these conditions I have nested choice and otherwise statements and I just wanted to make sure my statements are properly written. This is the basic structure of my route:
from("file:/test")
.choice()
.when(header("CamelFileName").endsWith(".txt"))
.bean(new ProcessFileBean())
.choice()
.when(exchangeProperty("processed").isEqualTo(true))
.to("sql: insert into table (id, file) values (1, file)")
.otherwise()
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
logger.info("File has not been processed");
}
});
Also, can I catch any exceptions from the route, for example during the database insert process and log them to a file?
Yes the route should work using the route you have defined.
To catch exceptions use the OnException syntax to take some action based on a particular exception. For example OnException(IOException.class).handled(true).to("error");
You can also catch exceptions similar to the try catch in normal java. See here:
http://camel.apache.org/try-catch-finally.html
Related
Suppose I have a supplier and some exception occurs while invoking get method of that supplier.
Supplier<> supplier = () -> getSomething();
ResilienceDecorator.executeSupplier( //Edit 1 - Could be ResilienceDecorator.executeCallable
supplier,
resilienceConfiguration,
throwable -> {
log.error("Exception occured", throwable);
return null;
});
Edit 1 - Also same for ResilienceDecorator.executeCallable.
I need a consistent API to know what went wrong during execution i.e. What was the checked exception (Edit 1 - or Unchecked exception) causing the failure so I can
handle business logic. The throwable is not root cause of exception or whatever the supplier had thrown.
If we do not provide a throwable function like above then
every exception is wrapped in a ResilienceRuntimeException and we need a chain of getCause().getCause() to know what went wrong. This is internal to sdk which might change. Again a consistent API is needed.
Is there any alternative & consistent way to know what exception the supplier is throwing? I might need to bubble it up or write a user friendly message based on the exception occured, depending upon buisness logic.
Edit 1-
An example of my current situation.
Supplier<MatDocItm> supplier = () -> {
ErpHttpDestination erpHttpDestination = DestinationAccessor.getDestination(S4_SYSTEM).asHttp().decorate(DefaultErpHttpDestination::new);
return new CustomCommand(erpHttpDestination, params).execute();
}
try {
MatDocItm = ResilienceDecorator.executeSupplier(
supplier,
configuration
);
} catch (ResilienceRuntimeException e) {
throw new ReadException("Failed to read from SAP S/4HANA", e);
}
The supplier can throw runtime exceptions and based on these exceptions I want to give a User friendly error message with proper description.
The supplier can throw a DestinationAccessException (which is runtime exception) if a destination cannot be accessed, is not configured correctly, or does not fulfill certain prerequisites.
Not only the exceptions occured in supplier, I have TimeLimiterConfiguration & if timeout occurs then a TimeoutException can be thrown.
For above MatDocItm example the ResilienceRuntimeException.getCause() will give com.sap.cloud.sdk.cloudplatform.thread.exception.ThreadContextExecutionException. ResilienceRuntimeException.getCause().getCause() will reveal exception that actually caused the error i.e DestinationAccessException. Now ThreadContextExecutionException is internal to sdk and can change if sdk implementation changes. Will this implementation detail remain frozen and never change in future or is there any alternative way to get the root cause?
I would recommend ExceptionUtils.throwableOfType for matching exception type and sub classes.
Alternatively ExceptionUtils.throwableOfThrowable for matching exact type only.
The utility class already provided by dependency org.apache.commons:commons-lang3:3.10
Example:
#Nullable
YourException cause = ExceptionUtils.throwableOfType(throwable, YourException.class);
You can handle the nullable result in an If statement.
As a fan of fluent APIs, I would rather go with java.util.Optional or io.vavr.control.Option.
when we can handle it in single default Exception then Why we should use
Multiple Catches?
public static void main(String[] args) {
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception occurs");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBounds Exception occurs");
}
catch(Exception e)
{
System.out.println("Parent Exception occurs");
}
System.out.println("rest of the code");
}
If you are using specific exception, let's say SqlException, it will take care of all the possible exceptions codes but in if-else ladder, you need to define all the possible scenarios and there is a high chance you might miss some of them.
Please format your question properly from next time. Try to add what you have tried to solve the issue and explain your approach as much as possible.
Coming to the actual answer, you use multiple exceptions to provide specific handling mechanisms for each type of exception.
For example, if you want to handle DivideByZero exception seperately, like display a specific message to the user, you can do it by catching DivideByZero Exception, where as you can't perform the same operation using a generalized exception.
Adding to this, generalized exception can handle all the exceptions but then the message become generic. Here in we want message specific to each type of exceptions.
So two part question.
First, I recently encountered an error in a listener for a spring batch job. The job was processing 2000 records and successfully processed 1790 of them. The listener only processed about 100 records before it hit the exception and failed. There weren't any other exceptions in the job that got logged, aside from the same exception getting logged and preceded by
2018-01-10 15:21:24.798 ERROR 16416 --- [pool-5-thread-7] o.s.batch.core.job.AbstractJob : Exception encountered in afterStep callback
Is it possible that the exception that killed the listener also stopped the job before it finished processing/committing the remaining 210 records? It doesn't seem to make a lot of sense, but I'm not sure what else could've resulted in those records not being committed.
Second, was what order does spring batch read in input files? The 210 records in the above scenario were the first 210 in the file. I was wondering if that's because spring batch reads in files from the last line to the first line which would explain why those were the records that didn't get processed.
First of all, the processing logic should also be written in Tasklet, ItemReader, ItemWriter, and ItemProcessor. Listeners should only be used if you want to do something before/After the step. Listeners should be used to pass the information between the steps or if you want to save the information or call the other system which is not part of batch to inform that the step is completed.
The Spring batch source code where the call to the listener is made. If you check the source code for AbstracStep
try {
// Update the step execution to the latest known value so the
// listeners can act on it
exitStatus = exitStatus.and(stepExecution.getExitStatus());
stepExecution.setExitStatus(exitStatus);
exitStatus = exitStatus.and(getCompositeListener().afterStep(stepExecution));
}
catch (Exception e) {
logger.error(String.format("Exception in afterStep callback in step %s in job %s", name, stepExecution.getJobExecution().getJobInstance().getJobName()), e);
}
It is just catching the exception and moving on. Not sure, why it has been handled this way.
If you still want the spring batch to abort if something fails in the listener, all you need to do is catch the Exception in the listener and write the below code
public class YourListener implements StepExecutionListener {
#Override
public ExitStatus afterStep(StepExecution stepExecution) {
try {
yourcode ///////
} catch (Exception e) {
//log your error
stepExecution.setStatus(BatchStatus.FAILED);
stepExecution.addFailureException(e);
return ExistStatus.FAILED.addDescription(e);
}
return ExitStatus.COMPLETED;
}
}
I know this is something weird/wrong way to do it. But if you don't catch your exception, Spring batch will do it for you and just log. It will move ahead without aborting/stopping the batch execution.
I've came across code with functions which do nothing except check a conditional and throw an exception or do nothing depending on the outcome of the evaluation of the conditional.
The code would look something like this:
public string MyMethod() {
var name = "foo";
EnsureSuccess(name);
return name;
}
// Throws an exception if name is not "bar"
public void EnsureSuccess(string name) {
if (name != "bar")
{
throw new ArgumentException("Not bar!");
}
}
What is this called? Is this a named design pattern?
Also is this considered a good practice or a bad practice?
Example of code in the wild that uses this is the EnsureSuccessStatusCode method in HttpResponseMessage.cs which is part of System.Net.Http by Microsoft. (code, documentation)
That's not a design pattern. It's called programming assertion.
In computer programming, an assertion is a predicate (a true–false
statement) placed in a program to indicate that the developer thinks
that the predicate is always true at that place. If an assertion
evaluates to false at run-time, an assertion failure results, which
typically causes execution to abort.
In addition to the #Chris Eelmaa answer, I'll say that also Don't_repeat_yourself principle is used. Seems that EnsureSuccess(string name) is being used a lot..otherwise I don't see the point of extracting 2 lines of code.
Another interesting thing in the example is not like you pointed
throw new Exception("Not bar!");
But according to the MSDN Best Practices for Exceptions - Don't throw new Exception()
So please note that should be
throw new SpecificException("Not bar!");
Exception is a too broad class, and it's hard to catch without side-effects. Derive your own exception class, but derive it from Exception. This way you could set a specialized exception handler for exceptions thrown by the framework and another for exceptions thrown by yourself.
In the code example they are:
throw new ArgumentOutOfRangeException ();
throw new ArgumentNullException ("......");
throw new HttpRequestException (string.Format ("{0} ({1})", (int) statusCode, ReasonPhrase));
Imagine the code of EnsureSuccess being in-line at MyMethod:
public string MyMethod() {
var name = "foo";
// Ensure success
if (name != "bar")
{
throw new ArgumentException("Not bar!");
}
return name;
}
First, it would require a comment to explain what it's doing. Second, as pointed out before, you'd be repeating this code at every place you need to check this condition.
There's a refactoring (which is like a coding pattern) called extract method that results in what you see here.
Extract method (in this case, 'Don't repeat yourself') is also an example of information hiding, since the details of EnsureSuccess are hidden away in that method. If ever a decision was made to change the logic of how EnsureSuccess works, one only changes the single method, and everywhere that calls the method will not need changing.
It might be Visitor, where you put the functions in a class.
So maybe that class EnsureSuccess would act as some kind of validator.
Maybe this class' jobs are to execute all the exception handlings?
It can also be a Facade pattern.
This pattern is very common used as a validator.
Thank you,
This is a general programming question, not pertaining to any specific language.
A new programmer typically will write a method that calculates some value, then returns the value:
public Integer doSomething()
{
// Calculate something
return something;
}
public void main()
{
Integer myValue = doSomething();
}
But when an exception occurs during the calculation of something, what is the best way to handle the exception, especially when giving the user feedback? If you do a try/catch of the calculation of something and if an exception is caught, what do you return? Nothing was calculated, so do you return null? And once you return it (whatever it may be), do you need to do another try/catch in the parent method that checks to see if a valid value was returned? And if not, then make sure the user is given some feedback?
I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.
Is there a best practice or approach to this? Are there any good resources that one could access to learn more about the best way to handle this?
UPDATE for Clarification
Consider the following code:
public void main()
{
int myValue = getMyValue();
MyUIObject whatever = new MyUIObject();
whatever.displayValue(myValue); // Display the value in the UI or something
}
public Integer getMyValue()
{
try
{
// Calculate some value
} catch (exception e) {
// ??
}
return value;
}
I call the method to get some int value, then I return it. Back in main(), I do something with the value, like show it in the Log in this case. Usually I would display the value in the UI for the user.
Anyways, if an exception is caught in getMyValue(), so does value get returned but it's null? What happens in main() then? Do I have to test if it's a valid value in main() as well?
I need the program to handle the error accordingly and continue. Someone below suggested displaying the appropriate information in the UI from within the getMyValue() method. I see two potential issues:
It seems like I would be mixing the business logic with (in this case) the logic for the UI.
I would have to pass a reference of the MyUIObject to the getMyValue() or something so I could access it from within the function. In the above simple example that is no big deal, but if there is a BUNCH of UI elements that need to be updated or changed based off of what happens in getMyValue(), passing them all might be a bit much...
I've read a bunch about the fundamentals of all of this but I can't seem to find a straight answer for the above situation. I appreciate any help or insight.
I think you do not quite understand exceptions.
If you throw an exception, you do not return from the function normally:
public Integer doSomething()
{
throw new my_exception();
// The following code does NOT get run
return something;
}
public void main()
{
Integer myValue = doSomething();
}
The main advantages of exceptions are:
You can write your code as though everything is succeeding, which is usually clearer
Exceptions are hard to ignore. If an exception is unhandled, typically an obvious and loud error will be given, with a stack trace. This contrasts with error codes, where it is much easier to ignore the error handling than not.
I recommend this post by Eric Lippert, which discusses exceptions and when it is and is not appropriate to handle them.
UPDATE (in response to comment):
You can absolutely handle an exception and continue, you do this by catching the exception.
eg:
try
{
// Perform calculation
}
catch (ExceptionType ex)
{
// A problem of type 'ExceptionType' occurred - you can do whatever you
// want here.
// You could log it to a list, which will be later shown to the user,
// you could set a flag to pop up a dialog box later, etc
}
// The code here will still get run even if ExceptionType was thrown inside
// the try {} block, because we caught and handled that exception.
The nice thing about this is that you know what kind of thing went wrong (from the exception type), as well as details (by looking into the information in ex), so you
hopefully have the information you need to do the right thing.
UPDATE 2 in response to your edit:
You should handle the exception at the layer where you are able to respond in the way you want. For your example, you are correct, you should not be catching the exception so deep down in the code, since you don't have access to the UI, etc and you thus can't really do anything useful.
How about this version of your example code:
public void main()
{
int myValue = -1; // some default value
String error = null; // or however you do it in Java (:
try
{
getMyValue();
}
catch (exception e)
{
error = "Error calculating value. Check your input or something.";
}
if (error != null)
{
// Display the error message to the user, or maybe add it to a list of many
// errors to be displayed later, etc.
// Note: if we are just adding to a list, we could do that in the catch().
}
// Run this code regardless of error - will display default value
// if there was error.
// Alternatively, we could wrap this in an 'else' if we don't want to
// display anything in the case of an error.
MyUIObject whatever = new MyUIObject();
whatever.displayValue(myValue); // Display the value in the UI or something
}
public Integer getMyValue()
{
// Calculate some value, don't worry about exceptions since we can't
// do anything useful at this level.
return value;
}
Exceptions is a property of object oriented languages (OOL). If you use OOL, you should prefer exceptions. It is much better than to return error codes. You can find nice examples how the error-codes approach generates a vastly longer source code than exceptions based code. For example if you want to read a file and do something with it and save in a different format. You can do it in C without exceptions, but your code will be full of if(error)... statements, maybe you will try to use some goto statements, maybe some macros to make it shorter. But also absolutely nontransparent and hard to understand. Also you can often simply forget to test the return value so you don't see the error and program goes on. That's not good. On the other hand if you write in OOL and use exceptions, your source code focuses on "what to do when there is no error", and error handling is in a different place. Just one single error handling code for many possible file errors. The source code is shorter, more clear etc.
I personally would never try to return error codes in object oriented languages. One exception is C++ where the system of exceptions have some limitations.
You wrote:
I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.
[EDIT]
Actually, excetion can be seen as error code, which comes along with the relative message, and you as the programmer should know where your exception must be caught, handled and eventually display to the user. As long as you let the exception to propagate (going down in the stack of called functions) no return values are used, so you don't have to care about handling related missed values. Good exception handling is a quite tough issue.
As jwd replied, I don't see the point to raise an exception in a method and then handle the excpetion in the same method just to return an error value. To clarify:
public Integer doSomething(){
try{
throw new my_exception();}
catch{ return err_value;}
}
is pointless.