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

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.

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 SQLException separate according to errorcode

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

Getting stacktrace in logger

I am using log4j to log my exceptions. I want to log whatever I get in e.printStackTrace();
My code looks like this:
try {
} catch(Exception e) {
log.error("Exception is:::" + e);
}
But the content I get logged looks like this:
2012-02-02 12:47:03,227 ERROR [com.api.bg.sample] - Exception in unTech:::[Ljava.lang.StackTraceElement;#6ed322
2012-02-02 12:47:03,309 ERROR [com.api.bg.sample] - Exception is :::java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
But the content I expect is:
java.io.IOException: Not in GZIP format
at java.util.zip.GZIPInputStream.readHeader(Unknown Source)
at java.util.zip.GZIPInputStream.<init>(Unknown Source)
at java.util.zip.GZIPInputStream.<init>(Unknown Source)
at com.api.bg.sample.unGZIP(sample.java:191)
at com.api.bg.sample.main(sample.java:69)
I tried e.getMessage(), e.getStackTrace(); however I don't get the full stacktrace. Any suggestions?
You have to use the two argument form
log.error("my logging message", exception)
See http://www.devdaily.com/blog/post/java/how-print-exception-stack-trace-using-log4j-commons for more details.
Change your logging statement to:
log.error("Exception is: ", e);
It is actualy log4j that prevents the printing of the fulltime stacktrace. You should however set the exception as a second parameter for the error method.
If you use the below than e.toString() will be called which calls e.getMessage()
log.error("Exception is:::" + e);
However, to print full stack trace you can use the below:
log.error("Exception is:::" + ExceptionUtils.getStackTrace(e));
where ExceptionUtils is imported as org.apache.commons.lang3.exception.ExceptionUtils
log.log(LEVEL.ERROR,e.getMessage(),e);

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