Handling errors of type application/json when using webread
35 views (last 30 days)
Show older comments
Ciaran McAndrew
on 2 Jan 2020
Commented: Sylvain Lacaze
on 9 Jan 2020
Having trouble with how MATLAB interpret's the message of a server error when type is of application/json.
Problem
Calling a local API, the following error is returned:
{"errorCode":401,"message":"Access to mylocalapi not authorized"}
Calling this using webread in MATLAB, the following exception is generated. Note the message has been stripped out of the exception.
Error using matlab.internal.webservices.HTTPConnectionAdapter/copyContentToByteArray
The server returned the status 401 with message "" in response to the request to URL http://mylocalapi
Error in webread (line 125)
[varargout{1:nargout}] = readContentFromWebService(connection, options);
Assessment
The error handler in HTTPConnectionAdapter does not seem to find the message part of the error. The response was compliant with the odata and Google API standards, but need to recognise there is no clear standard here. My problem is that the content has been stripped out by the time the response is returned as an MException object.
The only way around this seems to be to define a custom ContentReader in weboptions, however this has a performance impact across the full application, due to local disk i/o and poor ContentReader code on the part of the user.
Otherwise, the HTTPConnector generates the following MException
e =
MException with properties:
identifier: 'MATLAB:webservices:StatusError'
message: 'The server returned the status 401 with message "" in response to the request to URL http://mylocalapi.'
cause: {0×1 cell}
stack: [11×1 struct]
e.stack(1)
ans =
struct with fields:
file: 'D:\MATLAB\R2018b\toolbox\matlab\external\interfaces\webservices\restful\+matlab\+internal\+webservices\HTTPConnector.m'
name: 'HTTPConnector.copyContentToByteArray'
line: 361
Might it be possible to extend the MException class to have a HTTPException with additional fields such as the full error response?
For info, the following weboptions are being sent with the request.
options =
weboptions with properties:
CharacterEncoding: 'auto'
UserAgent: 'MATLAB 9.5.0.1067069 (R2018b) Update 4'
Timeout: 5
Username: ''
Password: ''
KeyName: ''
KeyValue: ''
ContentType: 'json'
ContentReader: []
MediaType: 'application/json'
RequestMethod: 'get'
ArrayFormat: 'json'
HeaderFields: {1×2 cell}
CertificateFilename: 'D:\MATLAB\R2018b\sys\certificates\ca\rootcerts.pem'
Apologies if this is non-reproducable, however it is using a local service.
0 Comments
Accepted Answer
Sylvain Lacaze
on 8 Jan 2020
Hi Ciaran,
I'm not sure I completely understand what your API returns. It's not clear to me that the HTTP Response has a status code 401 and a Body "Access to mylocalapi not authorized", or if it returns some 2XX code with a JSON payload as you describe.
I'm not aware of a way to get "webread" to return the response payload in case of non 2XX or 3XX status code.
Maybe to get a better understanding of this, could you use the HTTP interface to see what response you get, using this starting snippet?
request = matlab.net.http.RequestMessage();
request.Method = 'GET';
request.Header = [ ...
matlab.net.http.field.ContentTypeField( 'application/json' ), ...
matlab.net.http.field.AcceptField( 'application/json' ), ...
];
response = request.send( 'https://www.google.com/doesntexist' );
disp( response )
disp( response.Body )
For reference, not the outcome of:
webreadResponse = webread( 'https://www.google.com/doesntexist' )
From this, you can see you get an MException, whose message is completely formed from the response.StatusLine. It makes no use of the response payload, that you can see in the reponse.Body.
Can you post what the reponse and response.Body would be in your case?
2 Comments
Sylvain Lacaze
on 9 Jan 2020
Hi Ciaran,
I'm glad I could help. One clarification on this excerpt of your comment:
it seems webread will only handle an error message if it is in plain text in the reponse payload
Webread uses the text from the StatusLine, and completely ignores the payload. The StatusLine is dictated by the HTTP spec, which universal. The payload on the other hand, could be anything. Also OData, and Google APIs are widely used, every API could return anything in the payload, making it unreliable to parse. Some API even return binary payloads.
In any case, I'll make sure your feedback gets logged in our system. Development will assess the idea of a customer error handler.
Best,
Sylvain
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!