I'm trying to insert some data into the table named rmas.
The table format is
|rcode|rname|vcode|vanme
Here, I set primary key for rcode.
When I'm inserting a record with existing rcode, it displays something like ORA-0000-1 unique constraint Violated..
If I'm using the following code, it displays the message even in the case of other errors.
catch(Exception e)
{
//out.println("rcode already exists");
}
So, I want to catch that primary key exception only and display as "rcode already exist". Is it possible? If yes, then how?
Thanks in advance
Exception is the parent of all the exception. If you have catch(Exception e) { } block written then all the exceptions will fall into this category. You need to find which exception the compiler is returning. Say if your compiler returns this exception SQLIntegrityConstraintViolationException then the following block would come
catch(SQLIntegrityConstraintViolationException e)
{
// Error message for integrity constraint violation
}
catch(NullPointerException e)
{
// Null Pointer exception occured.
}
catch(Exception e)
{
// Other error messages
}
In this way you can have any number of exception blocks. But make sure more specific exception types are first written and then the parent exceptions
You're catching an Exception, which is the superclass of all exceptions. By catching this you use the Pokémon Style ("Gonna catch 'em all!") which is, in general, a bad practice since you lose the ability to take different courses of action based on the particular exception that was thrown in that block of code.
Catch only the exception related to the constraint violation to avoid showing the message for every exception.
Why would you like to do this on a servlet escapes me, but I suggest you take a look at the architecture of your solution and provide a layered approach, catching this exceptions in the Persistence tier and returning your own result code, that defines which message should be displayed to the user.
Note: I used Result code and not Error code to allow returning a code for a successful operation.
I wouldn't have any such code in a servlet. I think it belongs in a class that lives in your persistence tier. Servlets are HTTP listeners; they shouldn't have database code in them.
Have your interface-based persistence class catch that exception and handle it appropriately. Write an inteface-based service that uses the persistence class to fulfill the use case. Let the servlet call the service and figure out what to display next based on what happens.
It's called a layered architecture. I'd recommend it highly.
In my case in a spring boot application, I used DataIntegrityViolationException to catch unique constraint like this:
try {
userRepository.save(user);
log.debug("Created Information for User: {}", user);
} catch (DataIntegrityViolationException e) {
}
I would catch in the following manner:
catch(Exception ex){
if(ex.getMessage().contains("UNIQUE KEY"))
return "Error - Unique Key Violation!!";
else if(ex.getMessage().contains("FOREIGN KEY"))
return "Error - Foreign Key Violation!!";
else
return "Other Error: " + ex.getMessage();
}
Hope that's simple and functional!!
Related
I am not able to understand why Java doesn't allow to change exception message of an exception of type Exception (or its superclass Throwable) once it has been created. It allows to change the stackTrace using setStackTrace but not the message.
The use case I have seems genuine to me and would appreciate some alternative.
Use case
I have a controller service X that calls let's say 10 other dependent services. To make debugging easy, if a dependent service throws some exception we want to surface some identifiers from service X to its upstream to identify the failed request easily. For this we have requestId which we create and set for each dependency.
Now to avoid duplication across all dependent services and simplify code, we can create a common interceptor that allows us to do some work before and after each call. Something like -
// do some work
requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);
try {
dependentService.call();
}
catch (Exception e) {
e.setMessage(e.getMessage() + ... + requestId);
throw e;
}
//do some work
But Java doesn't allow us to set message. At the same time, we want to preserve the exception and its type (which could be any of the custom types defined by dependent services), so I don't want to do something like throw new Exception(e.getMessage() + ...)
It's not really what it's meant for, but you could attach another exception with addSuppressed:
} catch (Exception e) {
e.addSuppressed(new ExtraInfoException(...));
throw e;
}
where ... contains the extra info you want to include.
The advantage of this over adding to the exception message is that you can define your ExtraInfoException so that it has the info you want in fields, rather than having to parse it back out of the exception message.
With that said, a more idiomatic way to attach more exception info it would be:
} catch (Exception e) {
throw new ExtraInfoException(e, ...);
}
which has exactly the same advantage of allowing you to return structured information, with the additional advantage that you can catch ExtraInfoException directly, rather than catching Exception and then hunting for the extra info reflectively.
Why doesn't Java have setMessage in Exception/Throwable classes?
The answer to your question is that they (the library designers) did not think that changing a message on an exception was a useful thing to do.
To a large degree1, the designers have taken the view that they shouldn't design the APIs to directly support all possible use-cases ... including the obscure ones that almost nobody will encounter. Like your one2.
And in your case, there are other ways to achieve what you are trying to do; see the other answers.
I did a quick search of the Java bugs database to see if someone else had put in an RFE to request a setMessage method for Throwable or Exception. I couldn't find anything. If your requirement was even slightly common, there would probably be an RFE with an explanation of why it was declined.
1 - Obviously, there are exceptions to this, but that is beside the point.
2 - Obviously you would disagree that your use-case is obscure, but that that is also beside the point. The question is why they haven't implemented this, not whether they were wrong. (Asking / debating whether they were wrong is off-topic, because it is a matter of opinion.)
Resetting a message it's some kind of rewriting the history. You have a catch block when you catch exception and handle them. If you need to throw an exception during the handling, it's a different problem and an exception should be different.
} catch (SomeException e) {
// here we have SomeException and we want to handle it.
// if we can't we throw a new one, because we have a problem with handling.
// if the handling problem cause is SomeException we put it at the cause.
throw new AnotherException("with some message", e);
}
And in the stacks trace we will see that we have AnotherException because of SomeException which gives us information about the root of problem.
Just simply throw new instance like this:
try {
...
} catch(Exception ex) {
throw new Exception ("new message", ex);
}
I am looking to create a exception factory
I have a service that connects to different data stores and these data stores throw a number of exceptions.
I do not want to return these exceptions to users of the service but instead return higher level exception
e.g. storeServiceTransientReadException
When connecting to the data store I will use a try, catch throw pattern; e.g for a Cassandra connection:
public ResultSet safeExecute(Statement statement) throws StoreServiceException {
try {
return session.execute(statement);
}
catch(QueryExecutionException ex){
log.error(ex);
StoreServiceException storeException = StoreServiceExceptionFactory.getTransientException(ex);
throw storeException;
}
In the cassandra example I want the factory to create a read or write storeServiceException exception depending on whether the exception is a ReadFailureException, ReadTimeoutException, WriteFailureException or WriteTimeoutException
For other data stores I want to follow the same pattern then users of the service will only have to worry about the service errors and not specific data store errors.
For the factory I was think something along the lines of (in pseudo):
public class ExceptionsFactory {
public StoreServiceTransientException getTransientException(Exception ex){
if ReadException
return StoreServiceTransientException("read exception ")
if WriteException
return StoreServiceTransientException("write exception ")
}
public StoreServiceNonTransientException getTransientNonException(Exception ex){
if ReadException
return StoreServiceNonTransientException("read exception ")
if WriteException
return StoreServiceNonTransientException("write exception ")
}
But I cannot find many online example of this which worries me.
It is a really bad idea?
I should just have lots more specific catch blocks that return the storeServiceException I want?
It is a really bad idea? In my opinion, yes. This is a bad idea. The expensive part of using Exception(s) is filling in the stack trace. If you pre-create and save the Exception you throw then the stack trace will be meaningless (or at least of greatly reduced value). You aren't currently logging stack traces, so I would also change
log.error(ex);
to
log.error("Caught exception: " + ex.getMessage(), ex);
And similarly instantiate exceptions with the underlying cause -
throw new storeServiceException("Exception in storage.", ex);
And the name should follow normal naming conventions. Java class names start with a capital letter - yours' looks like a variable.
What is Exception wrapping in Java? How is it useful in exception handling? How it differs from exception propagation?
Exception wrapping is when you catch an exception, wrap it
in a different exception and throw that exception.
Here is an example:
try{
dao.readPerson();
} catch (SQLException sqlException) {
throw new MyException("error text", sqlException);
}
Source: http://tutorials.jenkov.com/java-exception-handling/exception-wrapping.html
On the Other Hand
Exception Propagation: An exception is first thrown from the top of
the stack and if it is not caught, it drops down the call stack to the
previous method, if not caught there, the exception again drops down to
the previous method, and so on until they are caught or until they
reach the very bottom of the call stack.
Source: http://www.javatpoint.com/exception-propagation
I think Neeraj's answer is spot on. To add on to it, I think one particularly good case is to manage the number of exceptions thrown by abstracting exceptions. To expand on Neeraj's example:
class Manager {
public void sendPerson() throws ManagerException {
try{
Person person = dao.readPerson();
Socket socket = getSocket();
OutputStream os = socket.getOutputStream();
String personJson = objectMapper.writeValueAs(person);
os.write(personJson);
} catch (SQLException | SocketException | OutputStreamException | SerializationException e) {
throw new ManagerException("error text", e);
}
}
}
This way, the client only needs to do the following:
try {
manager.sendPerson();
} catch (ManagerException e) {
// Handle fail by manager
}
instead of worrying about the fine-grained details of what may have gone wrong in the manager.
A usecase would be to turn a checked exception into a runtime exception or vice versa.
Or it could just be a naming thing. Let's say you catch an SQLException at some point in your code, but you can reason that it's because the user is not logged in. Then you could catch it and throw your own custom NotLoggedInException.
This answer is taken from here : http://www.javapractices.com/topic/TopicAction.do?Id=77
Data can be stored in various ways, for example:
a relational database
text files
on the web (for example, fetching the weather forecast from a web site)
If the storage method changes, then the low level Exception objects thrown by the data access layer can also change. For example, when the data store is moved from text files to a relational database, IOException is replaced with SQLException.
In order to prevent such a change from propagating to higher layers, one can wrap such low level Exceptions in a generic "data exception" wrapper, designed exclusively to protect the higher layers from such changes.
Now we will see a example...
public class ResourceLoader {
public loadResource(String resourceName) throws ResourceLoadException {
Resource r;
try {
r = loadResourceFromDB(resourceName);
}
catch (SQLException e) {
throw new ResourceLoadException("SQL Exception loading resource "
+ resourceName: " + e.toString());
}
}
}
loadResource's implementation uses exceptions reasonably well. By throwing ResourceLoadException instead of SQLException (or whatever other exceptions the implementation throws), loadResource hides the implementation from the caller, making it easier to change the implementation without modifying calling code. Additionally, the exception thrown by loadResource() -- ResourceLoadException -- relates directly to the task it performs: loading a resource. The low-level exceptions SQLException and IOException don't directly relate to the task this method performs, and therefore will likely prove less useful to the caller. Further, this wrapping preserves the original exception's error message so the user knows why the resource could not load (perhaps because of a connection error or an incorrect username or password) and can take corrective action.
I am using Spring ROO.
In my web application I can create many users and save.
I can update the existing users as well.
For the update scenario we are using merge() method to update the existing data. In database, the column 'username' is unique. Following is the scenario.
The user create an user name 'Sean' with mobile number '6039274849'
The user create another user named 'Parker' with mobile number '8094563454'
When the user tries to update the second user 'Parker' with 'Sean', I am getting exception.
In the stacktrace I could see the following exception being the causes
caused by ConstraintviolationException
caused by SQLException
caused by TransactionSystemException
caused by PersistenceException
caused by TransactionRollbackException
I tried the do the following
public String merge()
{
try{
//code to merge
}
catch(????? e){
throw e;
}
}
I tried to add the above 5 exceptions in '????' . But I couldnot catch still.
Can anyone please tell which exception I need to add in '????' to catch the exception from the above list?
P.S: I am using Spring ROO. So I am changing code in .aj file. Please dont close this question as duplicate. I am expecting an answer from anyone for my issue before closing this question.
As a last resort, you can just catch the all-purpose exception
public String merge()
{
try{
//code to merge
}
catch(Exception e){
//handle e here.
}
}
Um, aren't you just rethrowing the exception in your catch? It should be the "most-recent" exception in the trace, so ConstraintValidationException.
Note that typically in Spring/Hibernate apps, the exception bubbling out of your code is what causes transactions to roll back. If you catch the exception, you will probably prevent that, which might lead to data inconsistencies.
When in doubt I try catching a Throwable and either add break point or log it out to see exactly what it is. Then change code accrodingly.
I had the same probelem lately. It seems that spring wrap exception in it's own exception class. I solved this problem with:
try {
...
}
catch(Exception e){
System.out.println(e.getClass().getName());
}
with that you will discover what exception has been realy thrown;
For my Java application, I am creating an instance of a user information object and populating it with a service that I don't control the source for.
The code looks like this:
// username given as parameter
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (Exception e) {
// Whatever
}
If LDAPService.findUser() can't locate a user, it will throw a NullPointerException and grind the rest of my application to a stop. It's okay if the user information isn't populated, so I want to be able to continue without causing everything else to start throwing exceptions.
Is there a way to do this?
I've upvoted Amir Afghani's answer, which seems to be the only one as of yet that actually answers the question.
But I would have written it like this instead:
UserInfo ui = new UserInfo();
DirectoryUser du = null;
try {
du = LDAPService.findUser(username);
} catch (NullPointerException npe) {
// It's fine if findUser throws a NPE
}
if (du != null) {
ui.setUserInfo(du.getUserInfo());
}
Of course, it depends on whether or not you want to catch NPEs from the ui.setUserInfo() and du.getUserInfo() calls.
You could catch the NullPointerException explicitly and ignore it - though its generally not recommended. You should not, however, ignore all exceptions as you're currently doing.
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (NullPointerException npe) {
// Lulz # your NPE
Logger.log("No user info for " +username+ ", will find some way to cope");
}
You are already doing it in your code. Run this example below. The catch will "handle" the exception, and you can move forward, assuming whatever you caught and handled did not break code down the road which you did not anticipate.
try{
throw new Exception();
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println("Made it!");
However, you should always handle an exception properly. You can get yourself into some pretty messy situations and write difficult to maintain code by "ignoring" exceptions. You should only do this if you are actually handling whatever went wrong with the exception to the point that it really does not affect the rest of the program.
It's generally considered a bad idea to ignore exceptions. Usually, if it's appropriate, you want to either notify the user of the issue (if they would care) or at the very least, log the exception, or print the stack trace to the console.
However, if that's truly not necessary (you're the one making the decision) then no, there's no other way to ignore an exception that forces you to catch it. The only revision, in that case, that I would suggest is explicitly listing the the class of the Exceptions you're ignoring, and some comment as to why you're ignoring them, rather than simply ignoring any exception, as you've done in your example.
You are actually ignoring exception in your code. But I suggest you to reconsider.
Here is a quote from Coding Crimes: Ignoring Exceptions
For a start, the exception should be logged at the very least, not
just written out to the console. Also, in most cases, the exception
should be thrown back to the caller for them to deal with. If it
doesn't need to be thrown back to the caller, then the exception
should be handled. And some comments would be nice too.
The usual excuse for this type of code is "I didn't have time", but
there is a ripple effect when code is left in this state. Chances are
that most of this type of code will never get out in the final
production. Code reviews or static analysis tools should catch this
error pattern. But that's no excuse, all this does is add time to the
maintainance and debugging of the software.
Even if you are ignoring it I suggest you to use specific exception names instead of superclass name. ie., Use NullPointerException instead of Exception in your catch clause.
You can write a try - catch block around the line you want to have ignored.
Like in the example code of yours. If you just continue your code below the closing bracket of the catch block everythings fine.
LDAPService should contain method like LDAPService.isExists(String userName) use it to prevent NPE to be thrown. If is not - this could be a workaround, but use Logging to post some warning..
Printing the STACK trace, logging it or send message to the user, are very bad ways to process the exceptions. Does any one can describe solutions to fix the exception in proper steps then can trying the broken instruction again?