How to get details of ClientResponseFailure in RestEasy Client? - jax-rs

How to get http response contents when status >=400 is returned. That's my code sample :
try {
ChatService client = ProxyFactory.create(ChatService.class, apiUrl);
client.putMessage(dto);
} catch (ClientResponseFailure ex) {
System.out.println(ex.getResponse().getEntity().toString());
}
This throws :
Exception in thread "main" org.jboss.resteasy.spi.ReaderException: java.io.IOException: Stream closed
at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:123)
at org.jboss.resteasy.client.core.BaseClientResponse.readFrom(BaseClientResponse.java:246)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:210)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:171)
at App.main(App.java:40)
Caused by: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:134)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at org.jboss.resteasy.client.core.SelfExpandingBufferredInputStream.read(SelfExpandingBufferredInputStream.java:58)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at org.jboss.resteasy.client.core.SelfExpandingBufferredInputStream.read(SelfExpandingBufferredInputStream.java:68)
at org.jboss.resteasy.util.ReadFromStream.readFromStream(ReadFromStream.java:30)
at org.jboss.resteasy.plugins.providers.ByteArrayProvider.readFrom(ByteArrayProvider.java:32)
at org.jboss.resteasy.plugins.providers.ByteArrayProvider.readFrom(ByteArrayProvider.java:23)
at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:105)
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:46)
at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:108)
at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:111)
... 4 more
I'd like to have more details than just status code 400.

Is that the exception you meant to send?
Unfortunately the RestEASY client framework doesn't support Exception marshalling per se, and instead adapts it into the HTTP framework. Exceptions should still be thrown on the server though. I've never done it, you can use ExceptionMappers for checked Exceptions.
http://docs.jboss.org/resteasy/docs/1.2.GA/userguide/html/ExceptionHandling.html

When debugging I noticed that the details I needed were in the 'streamFactory' object as a byte stream of XML. I found this help topic in the RestEasy docs about ClientResponse. It says
getEntity(java.lang.Class<T2> type)
where getEntity can marshal the output to the desired class. In my case, I have a custom class for errors returned from services called ServiceError. So, that was the class I passed to getEntity:
try {
serviceResult = proxy.addCustomer(customerName, customerProfile);
} catch (ClientResponseFailure ex) {
ClientResponse<String> cResp = ex.getResponse();
ServiceError myEntity = cResp.getEntity(ServiceError.class);
System.out.println("myEntity errorText=" + myEntity.getErrorMessage().getErrorText());
System.out.println("myEntity errorCode=" + myEntity.getErrorMessage().getErrorCode());
}

Related

Sleuth/zipkin with ControllerAdvice is not working

I found there is an old issue Sleuth/Zipkin tracing with #ControllerAdvice, but I meet the same problem with the latest version(spring-cloud-starter-zipkin:2.1.0.RELEASE), I debug it and find that the error is null, so zipkin just guess with statuscode. I have to throw the exception again to make zipkin notify the exception
error is null
zipkin result
ControllerAdvice
throw the exception again, it works
It makes perfect sense that it's null. That's because YOU control the way what happens with the caught exception. In your case, nothing, cause you swallow that exception.
If you want to do sth better, just add the error tag manually via the SpanCustomizer. That way you'll add the exception to the given span. It will then automatically get closed and reported to Zipkin (you can do sth else than ex.toString() of course.
#Slf4j
#RestControllerAdvice
#Order(Ordered.HIGHEST_PRECEDENCE)
public class ExceptionHanders {
private final SpanCustomizer customizer;
public ExceptionHanders(SpanCustomizer customizer) {
this.customizer = customizer;
}
#ExceptionHandler({RuntimeException.class})
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleRuntimeException(Exception ex) throws Exception {
this.customizer.tag("error", ex.toString());
return "testabcd";
}
}

Axis2 web service stub failing

We have a website written in Java that makes a web service call. Recently, we have noticed that we are recieving a null response from the web service (The endpoint is a 3rd party not maintained by us).
I've tracked down the point at which our code is failing and it's in our stub. See the code below, the code is failing between the two System.out.println lines. My problem is that no exception is thrown, so I don't know why the _operationClient.execute(true); fails. Would anyone have any idea how I can go about solving this?
public SuggestXResponseE suggestX(SuggestXE suggestX0)
throws java.rmi.RemoteException {
org.apache.axis2.context.MessageContext _messageContext = null;
try {
org.apache.axis2.client.OperationClient _operationClient = _serviceClient.createClient(_operations[0].getName());
_operationClient.getOptions().setAction("http://www.test.com/service/suggestX");
_operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);
addPropertyToOperationClient(_operationClient, org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR, "&");
// create a message context
_messageContext = new org.apache.axis2.context.MessageContext();
// create SOAP envelope with that payload
org.apache.axiom.soap.SOAPEnvelope env = null;
env = toEnvelope(getFactory(_operationClient.getOptions().getSoapVersionURI()),
suggestX0,
optimizeContent(new javax.xml.namespace.QName("http://www.test.com/service",
"suggestX")));
//adding SOAP soap_headers
_serviceClient.addHeadersToEnvelope(env);
// set the message context with that soap envelope
_messageContext.setEnvelope(env);
// add the message contxt to the operation client
_operationClient.addMessageContext(_messageContext);
System.out.println("Log message 1");
//execute the operation client
_operationClient.execute(true);
System.out.println("Log message 2");
org.apache.axis2.context.MessageContext _returnMessageContext = _operationClient.getMessageContext(
org.apache.axis2.wsdl.WSDLConstants.MESSAGE_LABEL_IN_VALUE);
org.apache.axiom.soap.SOAPEnvelope _returnEnv = _returnMessageContext.getEnvelope();
java.lang.Object object = fromOM(
_returnEnv.getBody().getFirstElement(),
SuggestXResponseE.class,
getEnvelopeNamespaces(_returnEnv));
return (SuggestXResponseE) object;
} catch (org.apache.axis2.AxisFault f) {
// Handle exception.
}
finally {
_messageContext.getTransportOut().getSender().cleanup(_messageContext);
}
}
System.out.println("Log message 1");
//execute the operation client
_operationClient.execute(true);
System.out.println("Log message 2");
If you're getting the first log message but not the second one, then one of two things is happening:
System.exit() is being called somewhere within _operationClient.execute(). You'd recognize this by the fact the process exits.
More likely, _operationClient.execute() is throwing something.
You say it's not throwing an exception, but it could be throwing an Error or some other kind of Throwable. It's not normally advised to catch non-Exception throwables, but you could add some code to do it temporarily:
try {
_operationClient.execute(true);
} catch (Throwable t) {
log.error(t);
throw t;
}
You might find that you're getting an OutOfMemoryError or a NoClassDefFoundError because some jar is missing from your deployment, for example.

Lync Client API exception - Specified method is not supported

I am developing simple chat application using CWE which sends messages by using contextual data. I'm having "Specified method is not supported" exception message. This exception occurs when I try to start chat with group. one-to-one chat works fine with no exception. since I'm having same code on both sender & receiver side, I'm confused that how to make this work. Please help.
My code snippet as as follows.
void method1()
{
//
//here I have code to send an IM saying "lets chat in extension window"
//
try
{
Dictionary<ContextType, object> context = new Dictionary<ContextType, object>();
context.Add(ContextType.ApplicationId, "{1226271D-64C9-4F24-B416-E6A583F45A1C}");
context.Add(ContextType.ApplicationData, "initial_data_request");
try { IAsyncResult res = conversation.BeginSendInitialContext(context, null, null); }
catch (Exception e1)
{
MessageBox.Show(e1.Data+"\n\n"+e1.Message);
}
}
catch (Exception ee)
{
MessageBox.Show("Client Platform Exception: " + ee.Message);
}
}
This is the method I call when my application starts. It is supposed to send initial context so that receiver clients when receive this should open my extension application.
I found the answer. It is showing that exception because contextual data will not work in a group conversation.
Found the related thread here..
http://social.msdn.microsoft.com/Forums/lync/en-US/b4e46648-7097-4348-8327-6864f1c12ab2/contextdata-in-a-group-conversation?forum=communicatorsdk

WP7: Unable to catch FaultException in asynchronous calls to WCF service

I am currently developing a Windows Phone 7 App that calls a WCF web service which I also control. The service offers an operation that returns the current user's account information when given a user's login name and password:
[ServiceContract]
public interface IWindowsPhoneService
{
[OperationContract]
[FaultContract(typeof(AuthenticationFault))]
WsAccountInfo GetAccountInfo(string iamLogin, string password);
}
Of course, there is always the possibility of an authentication failure and I want to convey that information to the WP7 app. I could simply return null in that case, but I would like to convey the reason why the authentication failed (i.e. login unknown, wrong password, account blocked, ...).
This is my implementation of the above operation (for testing purposes, all it does is throwing an exception):
public WsAccountInfo GetAccountInfo(string iamLogin, string password)
{
AuthenticationFault fault = new AuthenticationFault();
throw new FaultException<AuthenticationFault>(fault);
}
Now, if I call this operation in my WP7 app, like this:
Global.Proxy.GetAccountInfoCompleted += new EventHandler<RemoteService.GetAccountInfoCompletedEventArgs>(Proxy_GetAccountInfoCompleted);
Global.Proxy.GetAccountInfoAsync(txbLogin.Text, txbPassword.Password);
void Proxy_GetAccountInfoCompleted(object sender, RemoteService.GetAccountInfoCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}
}
The debugger breaks in Reference.cs, saying that FaultException'1 was unhandled, here:
public PhoneApp.RemoteService.WsAccountInfo EndGetAccountInfo(System.IAsyncResult result) {
object[] _args = new object[0];
PhoneApp.RemoteService.WsAccountInfo _result = ((PhoneApp.RemoteService.WsAccountInfo)(base.EndInvoke("GetAccountInfo", _args, result)));
return _result;
}
BEGIN UPDATE 1
When pressing F5, the exception bubbles to:
public PhoneApp.RemoteService.WsAccountInfo Result {
get {
base.RaiseExceptionIfNecessary(); // <-- here
return ((PhoneApp.RemoteService.WsAccountInfo)(this.results[0]));
}
}
and then to:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
After that, the app terminates (with or without the debugger).
END UPDATE 1
Now, I would love to catch the exception in my code, but I am never given the chance, since my Completed handler is never reached.
Based on similar questions on this site, I have already tried the following:
Re-add the service reference --> no change
Re-create a really simple WCF service from scratch --> same problem
Start the app without the debugger to keep the app from breaking into the debugger --> well, it doesn't break, but the exception is not caught either, the app simply exits
Tell VS 2010 not to break on FaultExceptions (Debug > Options) --> does not have any effect
wrap every line in my app in try { ... } catch (FaultException) {} or even catch (Exception) --> never called.
BEGIN UPDATE 2
What I actually would like to achieve is one of the following:
ideally, reach GetAccountInfoCompleted(...) and be able to retrieve the exception via the GetAccountInfoCompletedEventArgs.Error property, or
be able to catch the exception via a try/catch clause
END UPDATE 2
I would be grateful for any advice that would help me resolve this issue.
The framework seems to read your WsAccountInfo.Result property.
This rethrows the exception on client side.
But you should be the first to read this property.
I don't know your AuthenticationFault class, does it have a DataContractAttribute and is it a known type like the example in
http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx ?
I believe I had the same problem. I resolved it by extending the proxy class and calling the private Begin.../End... methods within the Client object rather than using the public auto-generated methods on the Client object.
For more details, please see:
http://cbailiss.wordpress.com/2014/02/09/wcf-on-windows-phone-unable-to-catch-faultexception/

Retrieving parameter values using Microsoft Enterprise Library Exception Handler

We are using Enterprise Library for all our logging and exception handling needs in our app. We have added an email listener to send all the caught exceptions in email to the administrator. One requirement is that when an exception occurs in a method we need to retrieve the parameter values of the method if any and attach it to the exception details in the email sent. Is it possible without writing a custom logger?
Just create a custom exception, setting the message to the parameters:
try {
...
} catch(Exception ex) {
var customException = new CustomException(ex, string.format("Param1 {0}, Param2 {1}", param1, param2));
bool rethrow = ExceptionPolicy.HandleException(customException, PolicyName);
}
verified that in fact the ExceptionFormatter class will indeed traverse all inner exceptions, so your CustomException could be as simple as
public class CustomException : Exception
{
public CustomException(string message, Exception innerException) : base(message, innerException)
{
}
}