I'm new to Camunda and I've been trying to get my head around the way it handles retries. Given the code below, is it possible to trigger a retry only when error_type_1 is caught?
} catch (error_type_1 e) {
log.error(e);
} catch (error_type_2 e) {
log.error(e);
you can add the retry and also retry after what time to your tasks initiator property
reference
Is this a code from your java delegate? In that case, you need to throw exception to trigger an incident.
I'm not sure what you are trying to achieve, but I can think of two options:
1) Rethrow a BpmnError, which will cause a business exception which you can handle in some error events. https://docs.camunda.org/javadoc/camunda-bpm-platform/7.3/org/camunda/bpm/engine/delegate/BpmnError.html
2) Implement custom IncidentHandler https://docs.camunda.org/manual/7.5/user-guide/process-engine/incidents/#implement-custom-incident-handlers
Related
I have a Docker container with a Java application that uses a DB to persist some data. My application has a class that extends another one that is not code of mine (specifically SinkTask, a class from Kafka that is used to transfer data from Kafka to another system). When the application starts it opens a connection to the database. Sometimes, the database closes the connection and tasks start to fail. The exceptions thrown by these failures are catched in one part of my code and I can think of different ways to handle them:
1. Simply executing the code from within the application that stops and starts the connection again
2. Restarting the Docker container, creating a new connection in the process
I think the best solution is number 1. However, I wanted to know how could I trigger the second situation. My guess is that I should throw a new Exception in the catch block capable of terminating the application (remember that the SinkTask part of the code is out of my control). Would this be a good solution? Which kind of Exception should I throw in this case?
This is the part of the code where I catch the exception
private void commitCollections() {
for (SinkCollection sc : collections.values()) {
try {
commitCollection(sc);
} catch (Exception e) {
LOG.error("Error flushing collection " + sc.getTableName(), e);
}
}
transactionRecordCount = 0;
try {
connection.commit();
} catch (SQLException e) {
LOG.error("Commit error", e);
}
}
Throwing an Exception and letting it propagate in order to terminate the application is a perfectly nice solution. IMO, using System.exit(exit_code) would be better because it clearly describes what that code is doing.
In addition, docker will display the exit_code in the status of the container (docker ps -a), thus helping differentiate between different error conditions. When an uncaught exception is thrown the exit code is always 1.
Hope that helps.
Everyone talks about how important exception handling is. I have never had the need to handle them until recently:
try {
$pdo = new PDO($dns);
} catch (Exception $e) {
throw new Exception($e);
}
Another more general example would be:
if ($something) {
throw new Exception('Ouch! I can't do that!');
}
After a little online research, I found that many examples/solutions online simply echo them. (PDO Exception Questions - How to Catch Them) Some don't have solutions. (Catching PDOException in lower layer and re-throwing as different exception to upper layer) & (Where to catch exception in PHP MVC application?) And others, I just dont understand. (Where to catch exceptions)
Question #1: Where should I catch exceptions; in the Model or Controller of a MVCish framework?
Question #2: What should catching it do? Log it, email it, display 503?
I am a .net guy and for me best practices for catching exceptions:
Catch it as late as possible.
Write a common code to catch exception.
Catch it at controller level and log it somewhere with complete stack trace (ETW, Log file, DB etc.).
Redirect user to some good looking error page. Only controller can do this.
We are using a web service which throws 3 types of custom web service faults i.e. ServiceException, ConnectionException and InvalidDataException.
Along with these catch blocks, we have also put in the catch block for RemoteAccessException which is the spring's runtime exception.
catch (org.springframework.remoting.RemoteAccessException remoteAccessExc) {
}
While testing the above listed custom exceptions, we found that all these 3 types of exceptions are not getting catched in their respective catch blocks. Instead all gets catched in the last catch block which is the RemoteAccessException. We found during debugging the exception object of soap fault which is of type org.springframework.remoting.jaxws.JaxWsSoapFaultException that the service is throwing the correct faults.
My concern is why these faults are not falling into their own catch blocks. The service itself tells us to handle these exceptions while placing the service call.
When I hit the service through proxy java client, the faults fall correctly into their respective blocks. If there would have been a problem with POJO's then they shouldn't have worked in this case also. But they are working in this case(when hit through java proxy client) which means no problem in POJOs.
We are using spring-2.5.6.jar.
Since you are keeping different catch blocks and the fault object is getting overridden, do the following:
Check whether the fault object is null or not in each catch block, so that when the fault is thrown, it won't get overridden in any other catch block. This is because you put the not null check at every entry of catch block.
try{
//////
}Catch(IllegalArgumentException e){
create fault object;
throw fault;
}
Catch(Exception e){
///check whether fault object is not null
if(fault!=null){
throw fault;
}else{
///another fault object
throw fault1;
}
What is the correct pattern for handling OLE in a (REST) web service? this is what I'm doing now, for example,
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
...
...
...
try {
try {
em.getTransaction().begin();
// ... remove the entity
em.getTransaction().commit();
} catch (RollbackException e) {
if (e.getCause() instanceof OptimisticLockException) {
try {
CLog.e("optimistic lock exception, waiting to retry ...");
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
doDelete(request, response);
return;
}
}
// ... write response
} catch (NoResultException e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
return;
} finally {
em.close();
}
}
anytime you see a sleep in the code, there's a good chance it's incorrect. Is there a better way to handle this?
another approach would be to immediately send the failure back to the client, but I'd rather not have them worry about it. the correct thing seems to do whatever is required to make the request succeed on the server, even if it takes a while.
If you get an optimistic locking exception, it means that some other transaction has committed changes to entities you were trying to update/delete. Since the other transaction has committed, retrying immediately might have a good chance to succeed.
I would also make the method fail after N attempts, rather than waiting for a StackOverflowException to happen.
The "politically correct" answer in rest, is to return an HTTP 409 (Conflict) witch matches perfectly with the idea of optimistic locking. Your client should manage it, probably by retring a few seconds later.
I wouldn't add the logic to retry in your app, as your client will already handle situations when you return a 40X code.
By the way, catch (InterruptedException e) {} is always a bad idea, because the system has asked your computation to cancel, and you are ignoring it. In the context of a web service, an InterruptedException would be another good reason to signal an error to the client.
If you're just going to keep retrying until it works anyway, why not just disable optimistic locking? You should let the caller know that they made a decision based on out dated information! If you're in control of both sides an appropriate 400 code can be returned. If it's public it can be more friendly to arbitrary clients to just return 500. (Of course then you perpetuate the under-use of appropriate response codes! such a dilemma)
I have a code that throws a bunch of Exceptions but each of them only contains a printStackTrace() method as shown below
} catch (SecurityException e) {
// TODO Auto-generated catch block
System.err.println(e);
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Is this sufficient or do I need to include additional statements like System.err.println(e)? Usually, if an exception occurs I am able to trace the source with the above alone.
If there is something you can do to solve the problem, do it in the catch, if there is nothing you can do, then it is better to use a logging framework to register the exception than to use e.printStackTrace(); or System.err.println(e);
I personally recommend: http://www.slf4j.org/, but if you have masochistic tendencies you can try the very bad (but official) Java Logging API: http://download.oracle.com/javase/1.4.2/docs/guide/util/logging/ .
One extra advantage of SLF4J is that it can redirect its logging to the awful Java Logging API (that way you can use an elegantly designed API and still comform to the awfully designed (de jure not de facto) "standard"
SLF4J is easy to use, to log an exception all you have to do is write logger.error("some accompanying message", exception);, another of its advantages is that you can, for example, configure it to send you an email each time your application crashes (by using logback as the underlying logging engine)
It depends on the exceptions. Obviously, with printStackTrace() the exception will be printed for you to debug (or users to report to you). However there is no additional error handling.
Example:
If an IOException is thrown, you might want to show the user a error message specifying the exact error cause, or you might want to do another attempt, transparent for the user. Or you might want to abort the whole program if the operation is critical for the success of the whole task... etc.
If you want to trace the source e.printStackTrace() is enough.
Usually I put e.printStackTrace(); at DEBUG level. Also I add meaningful error message at ERROR level for the users.
I think you might be missing a bit about the basics of exceptions and exception handling.
The golden rule of exceptions is that they should be exceptional.
This is why you might have seen or read that you should never catch the base Exception - there is simply no way that your code can handle every time of exception.
So as a general rule you should only catch exceptions if you can handle them in a specific way. For example, if you're reading a user's details from a file and that fails you might choose to return a new user. What you don't want to do is simply catch the exception and log it. This leads to an application that is robust but simply swallows errors which leads to an extremely bad user experience.
If your method can't handle an exception it should simply not catch it and defer the exception handling to a higher level. This usually means an error message will be displayed to the user (at the top level).
If you can afford to use a logging framework like log4j, you'll be able to call
}catch(Exception e){ log.error("Exception occurred:",e}
making the log framework to log your custom message "Exception occurred" followed by the stack trace in your errorlog file