Java SQLException separate according to errorcode - java

I need to separate SQLExceptions according to ErrorCode. I have the following if statement in catch block but the else condition is printed always.
catch (SQLException ex) {
if (ex.getErrorCode() == 28502){
System.out.println("Username Problem");
}
else{
System.out.println("Other Problem");
}
Logger.getLogger(FirstTimeMainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
Actually, when I enter unexpected username when creating DB, the following SQLExceptions are thrown.
java.sql.SQLException: Failed to create database 'myDB', see the next exception for details.
//rest of exception.
Caused by: ERROR XJ041: Failed to create database 'myDB', see the next exception for details.
//rest of exception.
Caused by: ERROR XBM01: Startup failed due to an exception. See next exception for details
//rest of exception.
Caused by: ERROR 28502: The user name 'AAA.AAA' is not valid.
//rest of exception.
But my catch is always print Other Problem. How can I separate different SQLExceptions according to last ErrorCode?

--- SOLVED ---
Thanks for the routed comments for #blm first.
Trick is; Other coming Exceptions (1st and 2nd) has String values in their SQLState only numeric value in their ErrorCode.
SQLException chain 3rd exception has 28502 both SQLState and ErrorCode. This is the difference between 1st and 2nd Exceptions i think.
So i have changed my
Catch Block;
catch (SQLException se) {
do {
if(se.getSQLState().equals("28502")){
System.out.println("Username Problem");
}
else{
System.out.println("Other Problem");
}
} while ((se = se.getNextException()) != null);
}
Output is;
Other Problem
Other Problem
Username Problem

you should get the cause exceptions by using the 'getCause()' method of the SqlExeption object that was caught. then, you can cast the result to Exception and check its error code.
check this for more info: Throwable.getCause()
Edit:
SQLException temp = ex;
while(temp.getCause() != null)
{
temp = (Exception)temp.getCause();
}
// check if temp is SQLException and if it is check ((SQLException)temp).getErrorCode() == whatever you want

Related

complaining about logging and rethrowing the exception in sonar [duplicate]

I have the following piece of code in my program and I am running SonarQube 5 for code quality check on it after integrating it with Maven.
However, Sonar is complaining that I should Either log or rethrow this exception.
What am I missing here? Am I not already logging the exception?
private boolean authenticate(User user) {
boolean validUser = false;
int validUserCount = 0;
try {
DataSource dataSource = (DataSource) getServletContext().getAttribute("dataSource");
validUserCount = new MasterDao(dataSource).getValidUserCount(user);
} catch (SQLException sqle) {
LOG.error("Exception while validating user credentials for user with username: " + user.getUsername() + " and pwd:" + user.getPwd());
LOG.error(sqle.getMessage());
}
if (validUserCount == 1) {
validUser = true;
}
return validUser;
}
You should do it this way :
try {
DataSource dataSource = (DataSource) getServletContext().getAttribute("dataSource");
validUserCount = new MasterDao(dataSource).getValidUserCount(user);
} catch (SQLException sqle) {
LOG.error("Exception while validating user credentials for user with username: " +
user.getUsername() + " and pwd:" + user.getPwd(), sqle);
}
Sonar shouldn't bother you anymore
What sonar is asking you to do, is to persist the entire exception object.
You can use something like:
try {
...
} catch (Exception e) {
logger.error("Error", e);
}
I stumbled across the same issue. I'm not 100% sure if I'm completely right at this point, but basically you should rethrow or log the complete Exception. Whereas e.getMessage() just gives you the detailed message but not the snapshot of the execution stack.
From the Oracle docs (Throwable):
A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. Over time, a throwable can suppress other throwables from being propagated. Finally, the throwable can also contain a cause: another throwable that caused this throwable to be constructed. The recording of this causal information is referred to as the chained exception facility, as the cause can, itself, have a cause, and so on, leading to a "chain" of exceptions, each caused by another.
This means the solution provided by abarre works, because the whole exception object (sqle) is being passed to the logger.
Hope it helps.
Cheers.
If you believe that SQLException can be safely ignored, then you can add it to the list of exceptions for squid:S1166 rule.
Go to Rule-> Search squid:S1166.
Edit exceptions in Quality Profile.
Add SQLException to the list.

How do I display database trigger errors on a web application through Payara5

This is a standard error I receive for all Errors parsed from Database Triggers. I use Payara5 as the Application Server and Netbeans 8.2 IDE. In the instance on the picture, it was supposed to display "ID Number mandatory for applicants order that 18 years of age".
How do I make sure that the exact error as in the trigger, appears on the Web Application?
Given your stacktrace it looks like you need to remove the ExceptionUtils.findRootException(ex).getMessage() and just use ex.getMessage() since the thrown topmost Exception already contains the message that you need.
I would try with the following code when an Exception is thrown:
catch (Exception ex) {
JSFUtils.addMessageSessionError(
ExceptionUtils.formatException(AdHocTools.getCurrentMethodName(),
ex.getMessage());
}
However, ExceptionUtils.findRootException(ex).getMessage() might be there for a reason. There are cases where the topmost Exception is pretty general (e.g. an EJBException) and you really need to get to the root exception to get a meaningful message.
You could also try with this code which returns an SQLException if applicable and in other cases the root Exception.
catch (Exception ex) {
Throwable rootCause = ex;
while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
if ( rootCause instanceof java.sql.SQLException ) {
break;
}
rootCause = rootCause.getCause();
}
JSFUtils.addMessageSessionError(
ExceptionUtils.formatException(AdHocTools.getCurrentMethodName(),
rootCause.getMessage());
}

Java throwing wrong exception

I have created 2 custom exceptions to handle creating and persisting new users to a DB. The email (username) is the unique ID so if an email is duplicated an exception should be thrown since the unique ID already exists.
I'm also doing a password confirmation match. This confirmation match also will throw a custom exception of passwords don't match. These 2 piece work correctly independently of each other, however, when I put everything together and test, if a password confirmation fails its throwing the username already exists exception instead of passwords do not match exception. Why?
I've tried reordering the code but that doesn't seem to matter. I also tried if/else rather then just if but got the same results
//Username(email) must be unique
try {
//password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
//if passwords match - persist to DB
newGcUser.setPassword(bCryptPasswordEncoder.encode(newGcUser.getPassword()));
//Do NOT persist or show the confirm Password
newGcUser.setConfirmPassword("");
//set user
newGcUser.setName(newGcUser.getUsername());
return userRepository.save(newGcUser);
} catch (Exception e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}
}
I'm using Postman to test.
If I test an email I know isn't registered and mismatch the passwords I get the UsernameAlreadyExistsException message instead of the PasswordMatchException
This happens because your try {} catch (Exception e) {} block is catching the exception you're throwing within the block, throw the exception outside the try catch block and it should work catch :
// password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
// Username(email) must be unique
try {
// if passwords match - persist to DB
newGcUser.setPassword(bCryptPasswordEncoder.encode(newGcUser.getPassword()));
// Do NOT persist or show the confirm Password
newGcUser.setConfirmPassword("");
// set user
newGcUser.setName(newGcUser.getUsername());
return userRepository.save(newGcUser);
} catch (Exception e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}
(or catch a less generic exception eg the exception which is thrown from userRepository.save and rethrow it, then it will only catch that exception rather than all)
This is happening because your PasswordMatchException extends Exception and your catch block is catching it and throwing a UsernameAlreadyExistsException.
Reducing your code down to illustrate my point:
try {
throw new PasswordMatchException();
} catch(Exception e) {
throw new UsernameAlreadyExistsException();
}
Without knowing more about what kinds of exceptions your code can throw, you probably have two solutions:
1) Catch something more specific than Exception.
2) Move the password check outside your try/catch block.
Advise to break into different methods and make it modular:
private void matchPassword(..newGcUser..) throws PasswordMatchException{
// password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
}
Method to persist should catch the specific exception:
// Username(email) must be unique
try {
// if passwords match - persist to DB
...
return userRepository.save(newGcUser);
} catch (DataIntegrityViolationException e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}

Why isn't try/catch Exceptions working for Gson.fromJson()?

I've been getting com.google.gson.JsonSyntaxException from calling Gson.fromJson(), so added a catch(Exception) logic, but the error is never getting caught and just getting thrown!
Here's what I have:
Request request = new Request.Builder()
.url(getOrderUrlWithId)
.get()
.build();
try {
Response response = this.okHttpClient.newCall(request).execute();
GetOrderResult orderResult = gson.fromJson(gson.toJson(response.body().string()), GetOrderResult.class);
response.close();
} catch (IOException e) {
log.error("Error retrieving order : " + e.getMessage(), e);
throw new RuntimeException(e);
} catch (Exception e) {
log.error("Error happening for client PO: " + clientPO, e);
return null;
}
When I run the test I get "com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
"
Why isn't the error getting caught?
Here's the Stack trace:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.hub.fulfill.circlegraphics.getOrdersByCgOrderId(CircleGraphicsApi.java:164)
You need to catch JsonSyntaxException like this
For Kotlin
catch(e: JsonSyntaxException){
//show toast/snackabar/log here
}
For Java
catch(JsonSyntaxException e){
//show toast/snackabar/log here
}
Earlier I was also catching java.lang.IllegalStateException but it didn't worked.
Seems the root exception here is JsonSyntaxException and thus, we need to catch this one.
It worked for me!
when(...).thenReturn(null) points that you use some mocking library (jMock, Mockery or simular). And you define that if fromJson("test", Fulfillment.class) is called mock should return null. Actual method fromJson is not invoked as you already defined result.
If you want expection to be thrown, then remove line
when(gson.fromJson("test", Fulfillment.class)).thenReturn(null);
Figured it out. So turns out #Slf4j's log.error() call shows the exception as an error in Google StackDriver, hence telling me I've been getting millions of errors.

Print Alfresco exception

I've some problem printing the exception stack trace for Alfresco Exception.
On debug mode, step by step under Eclipse IDE I'm able to see the message when the exception is raised inspecting the Exception object but, when I send the error message to console output it's always null.
The exception is raised by this instruction:
try {
UpdateResult[] results = WebServiceFactory.getRepositoryService().update(cml);
}
catch (Exception ex) {
System.out.println(" " + ex.getStackTrace());
System.out.println("ERROR - createContent : " + ex.getMessage());
}
(in that case I tryed to write on a folder that not exists on repository) and inspecting the ex object on eclipse I can see the message:
java.lang.IllegalStateException: Failed to resolve to a single NodeRef with parameters (store=workspace:SpacesStore uuid=null path=/app:company_home/cm:UploadFromJava), found 0 nodes.
but ex.getMessage() returns null
Anyone could help me?
thanks,
Andrea
Implementing a method in this way:
NamedValue setNameProperty(String name) throws AlfrescoRuntimeException
{
try {
return Utils.createNamedValue(Constants.PROP_NAME, name);
}
catch (Exception ex) {
throw new AlfrescoRuntimeException(ex.getMessage());
}
}
The message is correclty printed with e.printStackTrace();
Try to replace your package in the log4j.properties from debug to error

Categories