API V1 RESTful. I got "Unknown error" when added line break to JSON. Is it OK? - rest

I'm testing API queries and sending POST with such body:
{
"books": "12",
"available": "true",
"id": "qwe2323-2342rfws-23r2rfew"
}
I got 200 response - OK.
But when I add line break to one of the string data, e.g.:
{
"books": "12",
"available": "true",
"id": "qwe2323-2342rfws-23r
2rfew"
}
I got 500 "Unknown error".
My question: Can the server recognize this error and return a response, for example, WRONG_ID? In fact, I just added a line break character to the identifier string. In theory, the script should see the forbidden symbol without problems and return the corresponding error. Can I give such a recommendation to fix this error?

The payload is INVALID which generates an exception at the server and responded with 500 as it cannot understand the data payload.
To check the payload and show a INVALID JSON DATA or through any custom message, you can check the payload on every POST request at the server side, as in below example for PHP programming language:
private function handleRequest(Request $request, Programmer $programmer)
{
// ...
if ($data === null) {
throw new \Exception(sprintf('Invalid JSON: '.$request->getContent());
}
// ...
}
Reference:
https://knpuniversity.com/screencast/rest/error-invalid-json#handling-invalid-json

Related

Unable to retrieve errors occured in Graphql mutation in flutter project

I am using the package graphql_flutter for GraphQL operations in my flutter app. The queries and mutations are going well but I cannot retrieve the errors by following the ways mentioned in their doc. Every time I receive a generic error message which is,
ClientException: Failed to connect to http://127.0.0.1:3006/graphql:
That I get by doing,
print(result.exception.toString());
My mutation looks like,
final MutationOptions mutationOptions = MutationOptions(
documentNode: gql(mutationString),
variables: vars
);
final QueryResult result = await _instance._client.mutate(mutationOptions);
if (result.hasException) {
// none of the following prints the expected error.
print(result.exception.clientException.message);
print(result.exception.graphqlErrors);
print(result.exception.toString());
}
print(result.data);
return result.data;
Whereas in the apollo client, My error is :
{
"errors": [
{
"message": "Invalid Phone number provided",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"otp"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
....
But I get none of that.
Note: The success response is coming as expected. I would like to know how can I get the graphql errors.
I found the problem. It is because android cannot connect to 127.0.0.1 or localhost from the emulator. I replaced the host with my local IP address and it is working fine now.
Put this in a try/ catch block and see if it can catch any exceptions
final QueryResult result = await _instance._client.mutate(mutationOptions);
the original question was how to get the graphql errors.
I'm using graphql: ^5.0.0
I checked the docs and found this example:
if (result.hasException) {
if (result.exception.linkException is NetworkException) {
// handle network issues, maybe
}
return Text(result.exception.toString())
}
but that just gave me the exception, not the error, I casted the result exception to the type of error and was able to get the message:
if (result.hasException) {
if (result.exception!.linkException is ServerException) {
ServerException exception =
result.exception!.linkException as ServerException;
var errorMessage = exception.parsedResponse!.errors![0].message;
print(errorMessage);
throw Exception(errorMessage);
}
}
this seems like a lot of work for a simple message, I wonder if there is another simpler built-in way to do it

How to pass Json Request body from one HttpRequest as a value in the next http request?

I'm trying to capture payload (in JSON) created from an HTTP request and pass it as a value to the next API request.
Step1: Create Http Request Payload. Sample Below:
{
"fdCustomerId":"${cuid}",
"account":{
"type":"CREDIT",
"credit":{
"cardNumber":"ENC_[${Output2}]",
"nameOnCard":"John Smith",
"cardType":"${cardtype}",
"cardSubType": "${cardsubtype}",
"billingAddress":{
"type":"work",
"country":"US",
"primary":true
}
}
Step2: Capture the final Payload into a variable using post processes
var requestBody = ctx.getCurrentSampler().getArguments().getArgument(0).getValue();
vars.put("requestBody", requestBody);
log.info("###########################################Request Body are:##########" + requestBody);
Step3: Pass the RequestBody variable as a value to the next HTTP request
{
"category": "GBS_ExecMetrics_UCom",
"consumed": false,
"data": { "Test Case Id": "AB_CMS_006_CC_001_500_",
"Account Number": "0001210520779700304",
"Primary Card Number": "**${requestBody}**",
"Secondary Card Number": "0000377883144114646",
"Run Date Time": "03/26/201917:30"}
}
When I hit that to the endpoint I get below error message:
{"Error":"BadRequest: Please provide a valid Json"...
How to convert this to string or include escape characters with a function and pass the request-body?
My bad with the sample request syntax taken in step 1.Above steps worked as-is.
Corrected the syntax as below and was able to pass the json. Thanks.
{
"fdCustomerId":"${cuid}",
"account":{
"type":"CREDIT",
"credit":{
"cardNumber":"ENC_[${Output2}]",
"nameOnCard":"John Smith",
"cardType":"${cardtype}",
"cardSubType": "${cardsubtype}",
"billingAddress":{
"type":"work",
"country":"US",
"primary":true
}
}
}
}

Need one help regarding fetching data value from response

Need one help regarding fetching data value from response.
Below is my response which I got after hitting URL.
{
"response": {
"Error Message": "Invalid Input missing",
"success": "false""
}
}
In this I want to read "Error Message" through POSTMAN test. For same reason I have written below code, but it is not working due to space between key.
var data = JSON.parse(responseBody);
tests ["Verify Error message"] = data.response.Error Message==="Invalid Input - Mandatory data(Company ID/source Id/SalesRep Ids/ContactPerson Ids) missing";
You're trying to use Error Message as a field with a space in it. Try:
tests ["Verify Error message"] = data.response.["Error Message"]==="Invalid Input - Mandatory data(Company ID/source Id/SalesRep Ids/ContactPerson Ids) missing";
This is not good to compare string.
In your response you must have like this,
{
"response": {
"Error Message": "Invalid Input missing",
"success": "false",
"responseCode" : 400
}
}
for more response codes, please go to this link,
http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
Then after do comparison,
var data = JSON.parse(responseBody);
if(data.reponse.responseCode == '400'){
// do stuff
}

PUT Request not happening at all in Fantom

I am having some trouble with PUT requests to the google sheets api.
I have this code
spreadsheet_inputer := WebClient(`$google_sheet_URI_cells/R3C6?access_token=$accesstoken`)
xml_test := XDoc{
XElem("entry")
{
addAttr("xmlns","http://www.w3.org/2005/Atom")
addAttr("xmlns:gs","http://schemas.google.com/spreadsheets/2006")
XElem("id") { XText("https://spreadsheets.google.com/feeds/cells/$spreadsheet_id/1/private/full/R3C6?access_token=$accesstoken"), },
XElem("link") { addAttr("rel","edit");addAttr("type","application/atom+xml");addAttr("href","https://spreadsheets.google.com/feeds/cells/$spreadsheet_id/1/private/full/R3C6?access_token=$accesstoken"); },
XElem("gs:cell") { addAttr("row","3");addAttr("col","6");addAttr("inputValue","testing 123"); },
},
}
spreadsheet_inputer.reqHeaders["If-match"] = "*"
spreadsheet_inputer.reqHeaders["Content-Type"] = "application/atom+xml"
spreadsheet_inputer.reqMethod = "PUT"
spreadsheet_inputer.writeReq
spreadsheet_inputer.reqOut.writeXml(xml_test.writeToStr).close
echo(spreadsheet_inputer.resStr)
Right now it returns
sys::IOErr: No input stream for response 0
at the echo statement.
I have all the necessary data (at least i'm pretty sure) and it works here https://developers.google.com/oauthplayground/
Just to note, it does not accurately update the calendars.
EDIT: I had it return the response code and it was a 0, any pointers on what this means from the google sheets api? Or the fantom webclient?
WebClient.resCode is a non-nullable Int so it is 0 by default hence the problem would be either the request not being sent or the response not being read.
As you are obviously writing the request, the problem should the latter. Try calling WebClient.readRes() before resStr.
This readRes()
Read the response status line and response headers. This method may be called after the request has been written via writeReq and reqOut. Once this method completes the response status and headers are available. If there is a response body, it is available for reading via resIn. Throw IOErr if there is a network or protocol error. Return this.
Try this:
echo(spreadsheet_inputer.readRes.resStr)
I suspect the following line will also cause you problems:
spreadsheet_inputer.reqOut.writeXml(xml_test.writeToStr).close
becasue writeXml() escapes the string to be XML safe, whereas you'll want to just print the string. Try this:
spreadsheet_inputer.reqOut.writeChars(xml_test.writeToStr).close

How to get the REST response message in ExtJs 4?

I'm building upon RESTFul Store example of ExtJs 4. I'd like my script to display errors provided by the REST server, when either Add or Delete request fails. I've managed to obtain the success status of a request (see the code below), but how do I reach the message provided with the response?
Store:
var store = Ext.create('Ext.data.Store', {
model: 'Users',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
url: 'test.php',
reader: {
type: 'json',
root: 'data',
model: 'Users'
},
writer: {
type: 'json'
},
afterRequest: function(request, success) {
console.log(success); // either true or false
},
listeners: {
exception: function(proxy, response, options) {
// response contains responseText, which has the message
// but in unparsed Json (see below) - so I think
// there should be a better way to reach it than
// parse it myself
console.log(proxy, response, options);
}
}
}
});
Typical REST response:
"{"success":false,"data":"","message":"VERBOSE ERROR"}"
Perhaps I'm doing it all wrong, so any advice is appreciated.
I assume that your service follows the REST principle and uses HTTP status codes other than 2xx for unsuccessful operations.
However, Ext will not parse the response body for responses that do not return status OK 2xx.
What the exception/response object (that is passed to 'exception' event listeners) does provide in such cases is only the HTTP status message in response.statusText.
Therefore you will have to parse the responseText to JSON yourself. Which is not really a problem since it can be accomplished with a single line.
var data = Ext.decode(response.responseText);
Depending on your coding style you might also want to add some error handling and/or distinguish between 'expected' and 'unexpected' HTTP error status codes. (This is from Ext.data.reader.Json)
getResponseData: function(response) {
try {
var data = Ext.decode(response.responseText);
}
catch (ex) {
Ext.Error.raise({
response: response,
json: response.responseText,
parseError: ex,
msg: 'Unable to parse the JSON returned by the server: ' + ex.toString()
});
}
return data;
},
The reason for this behavior is probably because of the REST proxy class not being a first class member in the data package. It is derived from a common base class that also defines the behavior for the standard AJAX (or JsonP) proxy which use HTTP status codes only for communication channel errors. Hence they don't expect any parsable message from the server in such cases.
Server responses indicating application errors are instead expected to be returned with HTTP status OK, and a JSON response as posted in your question (with success:"false" and message:"[your error message]").
Interestingly, a REST server could return a response with a non-2xx status and a response body with a valid JSON response (in Ext terms) and the success property set to 'true'. The exception event would still be fired and the response body not parsed.
This setup doesn't make a lot of sense - I just want to point out the difference between 'success' in terms of HTTP status code compared to the success property in the body (with the first having precedence over the latter).
Update
For a more transparent solution you could extend (or override) Ext.data.proxy.Rest: this will change the success value from false to true and then call the standard processResponse implementation. This will emulate 'standard' Ext behavior and parse the responseText. Of course this will expect a standard JSON response as outlined in your original post with success:"false" (or otherwise fail).
This is untested though, and the if expression should probably be smarter.
Ext.define('Ext.ux.data.proxy.Rest', {
extend: 'Ext.data.proxy.Rest',
processResponse: function(success, operation, request, response, callback, scope){
if(!success && typeof response.responseText === 'string') { // we could do a regex match here
var args = Array.prototype.slice.call(arguments);
args[0] = true;
this.callParent(args);
} else {
this.callParent(arguments);
}
}
})