How to exclude stacktrace from axis2 fault response - java

I have an Axis2 web service which throws different detail messages in the fault response to signal problems in the call.
At some point, due to server errors (others than the ones treated by the web service), in the fault detail string I get the full stacktrace of what happened. I do not want the client to see the stack trace, so (as a catch all errors) I want to output a simple "Server error" message with no stacktrace, no nothing.
What is the simplest way of intercepting fault responses and changing the fault message. Are modules the only way of (complicated) doing this?
Or, is there a configuration in Axis2 that says not to display stacktrace in fault?
Thanks!

I once had a similar problem. Not sure if there is some config to turn off the stacktrace showing, at least none that I could find at that moment (that would have been the best solution). Instead, I opted for a quick and dirty approach, mostly due to lack of time.
What I did was to provide Axis2 with the detail of the fault myself. The Axis2 servlet has a method called handleFault which deals with generating the fault. More exactly (deeper in the call) the MessageContextBuilder.createFaultEnvelope method is used to construct the fault element.
Having the stacktrace in the detail is the default behavior, but there are ways to specify your custom detail. One way is to use the the AxisFault's detail field in which you can add an OMElement (refer to AXIOM) to be placed into the fault. So you do something like:
public class MyServlet extends AxisServlet {
...
public void handleFault(MessageContext msgContext, OutputStream out, AxisFault e) {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMElement detail = factory.createElement(...);
e.setDetail(detail);
// now let axis do its thing with the new improved AxisFault
super.handleFault(msgContext, out, e);
}
}
Now, instead of the exception stacktrace, your detail will be added instead.

Axis2 uses Apache commons logging and the AxisFault messages that you are seeing are generated by code in Axis2 that looks similar to:
try {
executeMethod(httpClient, msgContext, url, getMethod);
handleResponse(msgContext, getMethod);
} catch (IOException e) {
log.info("Unable to sendViaGet to url[" + url + "]", e);
throw AxisFault.makeFault(e);
} finally {
cleanup(msgContext, getMethod);
}
[This code segment comes from org.apache.axis2.transport.http.HTTPSender]
So refer to apache commons logging user guide for instructions on how to set the logging levels and destination of the messages.
Hope this helps.

Can you not just catch the AxisFault
try {
// do stuff
} catch (AxisFault f) {
log.error("Encountered error doing stuff", f);
throw new IOException("Server error");
}

Related

Differences between error methods in log4j 1.x

In the logging part of the project I working for, I try to optimize the error messages that are shown in log management. Logging error messages is coded like this:
String errorMessage =" Problem with server "+"\n"+t.getMessage();
_logger.fatal(errorMessage);
Where t is a Throwable object and _logger is a Logger object, which is related to the log4j framework.
What I wonder is, what changes if I use _logger.fatal(errorMessage, t); instead of _logger.fatal(errorMessage);? If there is a major difference between them, Which one will be better to use?
Edit: I've just realised I copied "fatal" example instead of "error". However my question is same for fatal, too.
Practically all Java logging framework (alas, we have plenty of those...) support putting a Throwable as the last parameter.
This will result in a stack trace being logged, which can be extremely useful in diagnosing and fixing the problem.
I'd only ever not give the exception to the logger if the cause of the exception is really well established and printing the exception is just unnecessary noise. For example here:
try {
int port = Integer.parseInt(input);
// do something with the port
} catch (NumberFormatException e) {
logger.error("'{}' is not a valid port number: {}", input, e.toString);
}
Another case is when the exception is being re-thrown (and something else will eventually log it with more detail).
But not with a "Problem with server" (and at FATAL level no less). That looks like you want to get as much info as you can get.
Also note that in those cases, e.toString() is usually better than e.getMessage() because it also includes the name of the exception in addition to its message (which may be empty).

How to deal with errors in the Dropbox java API

While trying to develop an application that interacts with some cloud services I found the Dropbox API for Java to be especially confusing.
Specifically how to find the HTTP errors. For instance, with the Google Drive API if a request fails an IOException will be thrown however you can parse that IOException into a GoogleJsonResponseException which you can then extract the status code.
try {
File f =drive.files().create(fileMetadata).setFields("id").execute();
return f.getId();
} catch (IOException e) {
if (e instanceof GoogleJsonResponseException){
int statusCode = ((GoogleJsonResponseException) e).getStatusCode();
errorHandler(statusCode);
} else {
e.printStackTrace();
}
}
So is there something like this in the java dropbox API (Specifically 3.0.5).
I have been looking around and it seems like no but I wanted to make sure before I go down the rabbit hole of extremely specialized and complex coding like mentioned here. If it is could someone please give me an example of how I could properly handle these exceptions.
[Cross-linking for reference: https://www.dropboxforum.com/t5/API-support/How-to-get-error-responses-java-api/m-p/258338#M14989 ]
The Dropbox Java SDK automatically parses out the structured error data from the HTTPS response into native classes, and you can use as much or little of that specificity as you want. The structured error responses (generally JSON in the response body) offer much more granularity than just status codes.
For example, here's the code sample that is now missing from StackOverflow documentation from my post that you linked to:
try {
SharedLinkMetadata sharedLinkMetadata = client.sharing().createSharedLinkWithSettings("/test.txt");
System.out.println(sharedLinkMetadata.getUrl());
} catch (CreateSharedLinkWithSettingsErrorException ex) {
System.out.println(ex);
} catch (DbxException ex) {
System.out.println(ex);
}
And here's an example that shows how to check for a particular error case (i.e., a "path" error in that example).
That's the recommended way of handling these exceptions. I don't believe the SDK offers a way to retrieve the original unparsed error response. (If you don't want to use the SDK though, you can call the HTTPS endpoints yourself directly.)

java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED

I have a service that is expected to execute requests at ~5 or more requests/min. This service depends on Apache AsyncHttpClient. After every few minutes, the clients hits some condition which causes java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED. All requests to the client start failing with same exception message. After service is restarted, this cycle repeats.
It is really hard to debug this problem as the request execution failure surprisingly does not cause a callback to the failed() method of the AsyncResponse.
From what I could gather, there has been a fix HTTPCORE-370 in HttpCore NIO which solved a similar problem in 4.3.2. I am using the following version -
commons-httpclient-3.1.jar
httpasyncclient-4.1.1.jar
httpcore-4.4.4.jar
httpcore-nio-4.4.4.jar
Yet seeing this problem.
I've been dealing with this same exception in my application, and I finally found a helpful suggestion from this post - http://httpcomponents.10934.n7.nabble.com/I-O-reactor-status-STOPPED-td29059.html
You can use #getAuditLog() method of the I/O reactor to find out exactly
what exception caused it to terminate.
If you keep a reference to your ConnectionManager's IOReactor, you can call this method to get insight into the actual problem:
http://hc.apache.org/httpcomponents-core-4.4.x/httpcore-nio/apidocs/org/apache/http/impl/nio/reactor/AbstractMultiworkerIOReactor.html#getAuditLog()
Turns out I was doing something incredibly stupid in my own code. But I couldn't figure it out until I read the audit log.
If you see OutOfMemoryError before this, try this
-XX:MaxDirectMemorySize=512M
See https://issues.apache.org/jira/browse/HTTPASYNC-104
In my case, using Elasticsearch high level client, this exception is due to esclient.indexAsync(indexRequest,RequestOptions.DEFAULT,null)
I fixed it by add an action listeners in all async requests like this
esclient.indexAsync(indexRequest,RequestOptions.DEFAULT,
new ActionListener<IndexResponse>() {
#Override
public void onResponse(IndexResponse response) {
}
#Override
public void onFailure(Exception e) {
});
We had encountered the same issue and after lots of digging we found that a proper IOReactorExceptionHandler needs to provided to the HttpAsyncClient to avoid this. It's unfortunate that it's not well covered in the documentation.
Below is a snippet of our code where a more robust client builder tries to add the exception handler. Note that IOExceptions would still stop the I/O reactor as they might imply underlying network communication failures. You may adjust according to your unique use cases.
public RobustCloseableHttpAsyncClientBuilder withDefaultExceptionHandler() {
return withExceptionHandler(
new IOReactorExceptionHandler() {
#Override
public boolean handle(RuntimeException ex) {
logger.error(
"RuntimeException occurs in callback, handled by default exception handler and the I/O reactor will be resumed.",
ex);
return true;
}
#Override
public boolean handle(IOException ex) {
logger.error(
"IOException occurs in callback, handled by default exception handler and the I/O reactor will be stopped.",
ex);
return false;
}
});
}
Read this issue report in elasticsearch on Github for more exposure.

Binary Partial Writing Error

The code directly below attempts to send a message through a Java websocket; however, it occasionally produces the error (shown in the error stack below). Could anyone suggest what the problem'solution?
Code:
if(currSession != null && currSession.isOpen()) {
try {
currSession.sendMessage(new BinaryMessage(flowTable.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
Error Stack:
java.lang.IllegalStateException: The remote endpoint was in state [BINARY_PARTIAL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1015)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.binaryPartialStart(WsRemoteEndpointImplBase.java:963)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialBytes(WsRemoteEndpointImplBase.java:140)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendBinary(WsRemoteEndpointBasic.java:56)
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendBinaryMessage(StandardWebSocketSession.java:202)
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:107)
at com.hp.fucms.impl.TopoRestController.setFlowTable(TopoRestController.java:147)
Wrap your code in a synchronized method and funnel all calls through this new method. It appears the tomcat web socket cannot handle multiple messages being placed on the same websocket session at the same time. I have code which has been running flawlessly under Glassfish and fell apart instantly when I moved to Tomcat. I then altered my code as explained above and all my problems went away....and there was much rejoicing.

GWT client side unchecked exceptions

I've been working on a project which uses GWT (and SmartGWT), which is (are) new to me.
Whenever runtime exceptions are thrown in the client (no RPCs involved) nothing happens. By that I mean the method does not continue executing, there are no alerts, there is nothing in the Javascript error console or the SmartGWT error console.
I'm assuming this isn't normal practice in GWT applications. Where are these errors (e.g. null pointers) normally logged/handled?
Thanks in advance.
You can do catch them in the next way
GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
#Override
public void onUncaughtException(Throwable e) {
GWT.log(e.getMessage(), e);
}
});
You can replace the GWT.log by any other logging method.

Categories