-
Notifications
You must be signed in to change notification settings - Fork 566
Fix SOAP fault parsing #3
Changes from all commits
61127bc
6326bcc
1d2bdbf
acfc829
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,20 +10,14 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of | |
|
|
||
| package microsoft.exchange.webservices.data; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.io.OutputStream; | ||
| import javax.xml.stream.XMLStreamException; | ||
| import java.io.*; | ||
| import java.util.concurrent.Callable; | ||
| import java.util.concurrent.ExecutionException; | ||
| import java.util.concurrent.Future; | ||
| import java.util.zip.GZIPInputStream; | ||
| import java.util.zip.InflaterInputStream; | ||
|
|
||
| import javax.xml.stream.XMLStreamException; | ||
| import javax.xml.ws.http.HTTPException; | ||
|
|
||
| /** | ||
| * Represents an abstract service request. | ||
| */ | ||
|
|
@@ -697,41 +691,39 @@ protected SoapFaultDetails readSoapFault(EwsServiceXmlReader reader) { | |
|
|
||
| /** | ||
| * Validates request parameters, and emits the request to the server. | ||
| * | ||
| * @param request | ||
| * The request. | ||
| * | ||
| * @return The response returned by the server. | ||
| */ | ||
| protected HttpWebRequest validateAndEmitRequest( | ||
| OutParam<HttpWebRequest> request) throws ServiceLocalException, | ||
| Exception { | ||
| protected HttpWebRequest validateAndEmitRequest() throws ServiceLocalException, Exception { | ||
| this.validate(); | ||
|
|
||
| request = this.buildEwsHttpWebRequest(); | ||
| return this.getEwsHttpWebResponse(request); | ||
| HttpWebRequest request = this.buildEwsHttpWebRequest(); | ||
| try { | ||
| return this.getEwsHttpWebResponse(request); | ||
| } catch (HttpErrorException e) { | ||
| processWebException(e, request); | ||
|
|
||
| // Wrap exception if the above code block didn't throw | ||
| throw new ServiceRequestException(String.format(Strings.ServiceRequestFailed, e.getMessage()), e); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we should wrap the exception here either. The problem is the exception gets wrapped two or three times by this class and the problem with wrapping exceptions is that it makes handling the real exception much harder. Why are exceptions wrapped anyway? |
||
| } | ||
| } | ||
|
|
||
| /** | ||
| * <summary> Builds the HttpWebRequest object for current service request | ||
| * with exception handling. | ||
| * | ||
| * @return An IEwsHttpWebRequest instance | ||
| * @return An HttpWebRequest instance | ||
| */ | ||
| protected OutParam<HttpWebRequest> buildEwsHttpWebRequest() | ||
| throws Exception { | ||
| OutParam<HttpWebRequest> outparam = new OutParam<HttpWebRequest>(); | ||
| protected HttpWebRequest buildEwsHttpWebRequest() throws Exception { | ||
| try { | ||
|
|
||
| outparam.setParam(this.getService().prepareHttpWebRequest()); | ||
| HttpWebRequest request = this.getService().prepareHttpWebRequest(); | ||
| AsyncExecutor ae = new AsyncExecutor(); | ||
|
|
||
| // ExecutorService es = CallableSingleTon.getExecutor(); | ||
| Callable getStream = new GetStream(outparam.getParam(), | ||
| "getOutputStream"); | ||
| Callable getStream = new GetStream(request, "getOutputStream"); | ||
| Future task = ae.submit(getStream, null); | ||
| ae.shutdown(); | ||
| this.getService().traceHttpRequestHeaders( | ||
| TraceFlags.EwsRequestHttpHeaders, outparam.getParam()); | ||
| this.getService().traceHttpRequestHeaders(TraceFlags.EwsRequestHttpHeaders, request); | ||
|
|
||
| boolean needSignature = this.getService().getCredentials() != null | ||
| && this.getService().getCredentials().isNeedSignature(); | ||
|
|
@@ -762,72 +754,44 @@ protected OutParam<HttpWebRequest> buildEwsHttpWebRequest() | |
| memoryStream); | ||
| } | ||
|
|
||
| ByteArrayOutputStream serviceRequestStream = (ByteArrayOutputStream) this | ||
| .getWebRequestStream(task); | ||
| { | ||
| EwsUtilities.copyStream(memoryStream, serviceRequestStream); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| else { | ||
| ByteArrayOutputStream serviceRequestStream = this.getWebRequestStream(task); | ||
| EwsUtilities.copyStream(memoryStream, serviceRequestStream); | ||
| } else { | ||
| ByteArrayOutputStream requestStream = this | ||
| .getWebRequestStream(task); | ||
|
|
||
| EwsServiceXmlWriter writer1 = new EwsServiceXmlWriter(this | ||
| .getService(), requestStream); | ||
|
|
||
| this.writeToXml(writer1); | ||
|
|
||
| } | ||
|
|
||
| return outparam; | ||
| } catch (HTTPException e) { | ||
| if (e.getStatusCode() == WebExceptionStatus.ProtocolError.ordinal() | ||
| && e.getCause() != null) { | ||
| this.processWebException(e, outparam.getParam()); | ||
| } | ||
|
|
||
| // Wrap exception if the above code block didn't throw | ||
| throw new ServiceRequestException(String.format( | ||
| Strings.ServiceRequestFailed, e.getMessage()), e); | ||
| return request; | ||
| } catch (IOException e) { | ||
| // Wrap exception. | ||
| throw new ServiceRequestException(String.format( | ||
| Strings.ServiceRequestFailed, e.getMessage()), e); | ||
| throw new ServiceRequestException(String.format(Strings.ServiceRequestFailed, e.getMessage()), e); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Gets the IEwsHttpWebRequest object from the specifiedHttpWebRequest | ||
| * object with exception handling | ||
| * | ||
| * @param outparam The specified HttpWebRequest | ||
| * @param request The specified HttpWebRequest | ||
| * @return An HttpWebResponse instance | ||
| */ | ||
| protected HttpWebRequest getEwsHttpWebResponse( | ||
| OutParam<HttpWebRequest> outparam) throws Exception { | ||
| HttpWebRequest request = outparam.getParam(); | ||
| int code; | ||
|
|
||
| protected HttpWebRequest getEwsHttpWebResponse(HttpWebRequest request) throws Exception { | ||
| try { | ||
| request.executeRequest(); | ||
|
|
||
| code = request.executeRequest(); | ||
|
|
||
| } catch (HttpErrorException ex) { | ||
| if (ex.getHttpErrorCode() == WebExceptionStatus.ProtocolError | ||
| .ordinal() | ||
| && ex.getMessage() != null) { | ||
| this.processWebException(ex, request); | ||
| if (request.getResponseCode() >= 400) { | ||
| throw new HttpErrorException( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than wrapping this exception by the caller, should we wrap it here? This also makes this method always throws ServiceRequestException.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the exception handling/wrapping in this library is kind of an issue on its own. Every method seems to just throw generic Exceptions all over the place, instead of throwing specific exceptions which can be handled adequately. If you think I should wrap it here already, I'll make the change, but I'm unsure here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having a look at processWebException() that you have removed, it is used in 3 places in the file and it does handle several error cases. I wonder if the fix should make processWebException() handle the lack of headers instead of just not using it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, the fix is really that we do call The only place |
||
| "The remote server returned an error: (" + request.getResponseCode() + ")" + | ||
| request.getResponseText(), request.getResponseCode()); | ||
| } | ||
|
|
||
| // Wrap exception if the above code block didn't throw | ||
| throw new ServiceRequestException(String.format( | ||
| Strings.ServiceRequestFailed, ex.getMessage()), ex); | ||
| } catch (IOException e) { | ||
| // Wrap exception. | ||
| throw new ServiceRequestException(String.format( | ||
| Strings.ServiceRequestFailed, e.getMessage()), e); | ||
| throw new ServiceRequestException(String.format(Strings.ServiceRequestFailed, e.getMessage()), e); | ||
| } | ||
|
|
||
| return request; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order alphabetically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IntelliJ IDEA orders
javax.*imports beforejava.*imports by default. I'm not sure we want to change this as long as the coding standards for this project are undefined.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.