Sending JSON via Postman causes an error in my Node.js service - arrays

I created schema in node.js. It worked before I included arrays.
This is my schema code:
const Item = new item_Schema({
info:{
title:{type:String, required:true},
bad_point:{type:Number, 'default':0},
Tag:{type:String, required:true}
},
review:{
Review_text:{type:Array, required:true},
Phone_list:{type:Array, required:true},
LatLng_list:{type:Array, required:true}
}
});
Item.statics.create = function(info, review){
const list = new this({
info:{
title,
bad_point,
Tag
},
review:{
Review_text,
Phone_list,
LatLng_list
}
});
return list.save();
};
This is my register code:
exports.register = (req, res) => {
const { info, review } = req.body
const create = (list) => {
return Item.create(info, review)
}
const respond = () => {
res.json({
message: 'place route registered successfully'
})
}
const onError = (error) => {
res.status(409).json({
message: error.message
})
}
RouteReviewItem.findOneBytitle(title)
.then(create)
.then(respond)
.catch(onError)
}
And this is the Postman JSON raw code:
{
"info":"{
"title":"test title",
"badPoint":"0"
"Tag":"tag1"
}",
"review":"{
"Review_text":["1번리뷰", "2번리뷰", "3번리뷰"],
"Phone_list":"["010-0000-0000", "010-1111-1111", "010-2222-2222"],
"LatLng_list":["111.1111,111.1111", "222.222,222.222","333.3333,333.3333"]
}"
}
This is the error I get in Postman:
SyntaxError: Unexpected token in JSON at position 17
at JSON.parse (<anonymous>)
at parse (C:\MainServer\node_modules\body-parser\lib\types\json.js:89:19)
at C:\MainServer\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\MainServer\node_modules\raw-body\index.js:224:16)
at done (C:\MainServer\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\MainServer\node_modules\raw-body\index.js:273:7)
at emitNone (events.js:105:13)
at IncomingMessage.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1045:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
Is this a problem with postman? Or the node.js side?
I looked at the node.js book I was studying, but could not find any relevant information.

The code is fine, you have an issue with JSON you used for testing. For further testing and debugging, I suggest that you verify that the requests you send you the endpoint are correct by using a service like JSONLint (or any offlne tool that does the same). For the request you posted in the question, this service complains:
Error: Parse error on line 2:
{ "info": "{ "title": "test t
----------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'
Next time, before sending a request, make sure it is correct syntactically. That way you'll know that there is a problem with your code, and won't spend time debugging a non-existent issue.

Related

ReactJS testing causing a typeError: network request failed

I have been trying to simulate file-upload as a test for my react-app but that was generating the following error :
TypeError: Network request failed
at node_modules/whatwg-fetch/dist/fetch.umd.js:535:18
at Timeout.task [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:516:19)
This is my test: trying to upload a file and check if an alert is raised.
test("triggers alert when receiving a file with inadequate content", async () => {
renderComponent();
global.alert = jest.fn();
const fileContent = raw("./file.kml");
const fakeFile = new File(
[fileContent],
"file.kml",
{ type: "text/xml" }
);
const selectType = screen.getByTestId("select-type");
await fireEvent.change(selectType, { target: { value: "type" } });
const fileUploader = screen.getByTestId("file-uploader");
await fireEvent.change(fileUploader, {
target: { files: [fakeFile] },
});
await waitFor(() => {
expect(global.alert).toHaveBeenCalledWith(
"alert"
);
});
});
});
I am kind of confused, because file is received and parsed by the component and it raise the alert I need to check but still fails because of the network error.
PS: I tried to mock a fetch but still have the same problem.
Any help would be appreciated.
I have been getting the same
Network request failed: Connection refused
error while testing.
I have explored many threads but no luck.
Out of the blue starting the back end server worked for me. (Even though I used mock service worker that intercepts network calls, starting the back end server worked.)
I don't know why.
Also, I have used import fetch from 'isomorphic-fetch'; in setup-test.js instead of whatwg-fetch.
In the end try adding a timeout:3000 option to your waitFor.

Error when sending POST request from React app to Rocket backend returns failure

I'm writing a simple web with Rocket as backend and React as frontend.
The code snippet looks like this for login page
#[post("/login", data = "<data>")]
pub fn login(
conn: DbConn,
mut cookies: Cookies<'_>,
data: Form<LoginForm>,
) -> Result<JsonValue, NotFound<String>> {
let valid_account = match Account::find_by_email(&*conn, data.email.as_str()) {
Ok(account) => {
if account.password == data.password {
account
} else {
return Err(NotFound("Incorrect email or password!".to_string()));
}
}
Err(_) => return Err(NotFound("Incorrect email or password!".to_string())),
};
cookies.add_private(
Cookie::build(AUTH_COOKIE, valid_account.id.to_string())
.same_site(rocket::http::SameSite::Strict)
.finish(),
);
Ok(json!({
"email": valid_account.email,
"name": valid_account.name,
}))
}
Code for main.rs
fn main() {
rocket::ignite()
.mount("/", routes![
account::login::login,
],
)
.register(catchers![errors::unauthorized])
.attach(rocket_cors::CorsOptions::default().to_cors().unwrap())
.manage(establish_connection())
.launch();
}
and code for React when trying to send the post request
export const postForm = async (
pathUrl: string,
postInfo: { [name: string]: any }
) => {
let axiosConfig = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
},
};
try {
const response = await axios.post(
baseUrl + pathUrl,
querystringify.stringify(postInfo),
axiosConfig
);
return response.data as CurrentUser;
} catch (err) {
console.log(err);
return Promise.reject(err.response);
}
};
The code works fine it I enter the correct email and password.
However, it cannot capture the error message if I enter the wrong credentials.
Rocket log are the same between successful login and failure login which are
OPTIONS /login:
=> Error: No matching routes for OPTIONS /login.
=> Warning: Responding with 404 Not Found catcher.
=> CORS Fairing: Turned missing route OPTIONS /login into an OPTIONS pre-flight request
=> Response succeeded.
POST /login application/x-www-form-urlencoded:
=> Matched: POST /login (login)
=> Outcome: Success
=> Response succeeded.
and the error log in browser I captured was Error: "Request failed with status code 404" which was not the expected error message hard coded inside post function.
I believe it has something to do with Option or preflight processed inside Rocket which maybe in the purpose of security. But how can I suppress the system error and let my code to take over?
I have read previous SO post like state undefined: while sending post request from react app and GitHub issues like https://github.com/SergioBenitez/Rocket/issues/25. And still cannot find answer for my problem.
Thanks in advance!
Apparently I made several mistakes here due to unfamiliar with Rocket and React.
List here in case someone made the similar mistakes.
The 404 status code is from the first code snippets Result<JsonValue, NotFound<String>>. So if we write the return type as Result<JsonValue, Unauthorized<String>>, it would return 401 as unauthorized user.
Second, axios only receives json type and cannot parse string (correct me if I'm wrong). So we need to change the return type in server to Result<JsonValue, Unauthorized<JsonValue>>.

React-Apollo catch when server is down

In my React ApolloGraphQL app with a node server, I'm trying to have it catch errors when my node server is down. All works great and normal when the node server us up... graphQL errors are caught and displayed. But when I stop the node server, I get a runtime error that I can't avoid. When the node server is down, the server responds with a 503 Service Unavailable response and an html page that isn't JSON.
The apollo client is set up like this:
const client = new ApolloClient({
assumeImmutableResults: true,
fetchOptions: {
credentials: "include"
},
fetch: fetch,
onError: ({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,),);
if (networkError) {console.log(`[Network error]: ${networkError}`);}
response = {errors:null};
},
cache: new InMemoryCache({
freezeResults: true,
dataIdFromObject: obj => {
let dataId = null;
switch (obj.__typename) {
default:
dataId = defaultDataIdFromObject(obj);
}
return dataId;
},
cacheRedirects: {
Query: {
productVariant: (_, args, { getCacheKey }) => {
const cacheKey = getCacheKey({ __typename: "ProductVariant", ...args });
return cacheKey;
}
}
},
}),
});
The above onError block response with this message:
Error: Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
I have the mutation set up this way:
const [mutateVariant, {data, error, loading}] = useMutation(UPDATE_PRODUCT_META);
And I call it like so:
mutateVariant({ variables: {inputM: {...buildMetaInput(editedData)} },
errorPolicy: 'ignore', onError: (error) => Logger("Error:", error)});
You can see I've tried it with different errorPolicy settings and adding an onError callback.
But I keep getting unhandled runtime errors and don't seem to be able to catch and handle them:
Unhandled Runtime Error
Error: Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Call Stack
ApolloError webpack-internal:///./node_modules/apollo-client/bundle.esm.js (76:28)
error webpack-internal:///./node_modules/apollo-client/bundle.esm.js (1041:48)
notifySubscription webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
error/< webpack-internal:///./node_modules/apollo-client/bundle.esm.js (880:76)
error webpack-internal:///./node_modules/apollo-client/bundle.esm.js (880:27)
notifySubscription webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
error webpack-internal:///./node_modules/apollo-link-error/lib/bundle.esm.js (53:34)
notifySubscription webpack-internal:///./node_modules/zen-observable/lib/Observable.js (140:18)
onNotify webpack-internal:///./node_modules/zen-observable/lib/Observable.js (179:21)
error webpack-internal:///./node_modules/zen-observable/lib/Observable.js (240:15)
createHttpLink/</</< webpack-internal:///./node_modules/apollo-link-http/lib/bundle.esm.js (92:26)
the returned error data from the useMutation hook:
graphQLErrors: Array []
message: "Network error: JSON.parse: unexpected character at line 1 column 1 of the JSON data"
​networkError: {…}
​ ​bodyText: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>503 Service
Unavailable</title>\n</head><body>\n<h1>Service Unavailable</h1>\n<p>The server is temporarily unable
to service your\nrequest due to maintenance downtime or capacity\nproblems. Please try again later.
</p>\n<p>Additionally, a 503 Service Unavailable\nerror was encountered while trying to use an
ErrorDocument to handle the request.</p>\n</body></html>\n"
name: "ServerParseError"
​​ response: Object { }
​​ statusCode: 503
How do I catch this error?
The mutateVariant function returns a promise. Try adding a .catch() after it is called.
mutateVariant().catch(() => {...});

Angular2 - send object in http.post request body

I am working on Angular2 web project, in my ts class I have an object :
Object: any= {
"first":null,
"second":null,
"third": null,
}
I want to send the object in http.post request body. I tried the next code, but it doesnot work;
method() {
const url='/pathname/';
return this.http.post(url, this.Object).pipe(map((data:any)=>data));
}
I got an error in console:
error : HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: "OK",url: "http://localhost:8080/path", ok: false,..}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for
http://localhost:8080/path 400 OK"
name: "HttpErrorResponse"
ok: false
status: 400
statusText: "OK"
url: "http://localhost:8080/path"
Can you explain me how to send typescript object in post request body ? Thank you in advance
You need to subscribe to the post observable returned by method function. It is done like this.
this.method().subscribe(
res => {
// Handle success response here
},
err => {
// Handle error response here
}
);
you should subscribe the post method because this method of http class returns a observable.
you can rewrite your code as:-
method() {
const url='/pathname/';
return this.http.post(url, this.Object).subscribe( resp=> {
const data = resp; // response you get from serve
}, error => {
console.log(error); //error you get from server
});
}
you are getting the 400 bad request error, the payload keys are mis matching with the middle wear. please suggest pass the correct params into Request object.

How to handle api errors using aws-amplify?

I'm currently trying to POST data to my aws lambda functions triggered by aws api-gateway using the aws-amplify react lib.
Here is the code :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(console.log(err))
In the main case, everything is OK.
But my lambda function is design to validate the input data and return a status code 400 with a returned payload looking like that :
{
"errors": [
{
"field": "title",
"message": "This field is required"
}
]
}
I would like to catch those errors in order to display them in the frontend but aws-amplify seems to have an undocumented behavior.
By default, status code 400 returned are throw with a default error message :
Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
Is there a way to get the returned payload instead of this magical error?
It turns out that under the hood, aws-amplifyuse Axios to make http calls.
When using Axios, you have to console.log(error.response): https://github.com/axios/axios/issues/960
Here is the fix I've made :
API.post("snippets","snippets/", {
body: data,
}).then(response => response).catch(error => console.log(error.response.data))
A Pull Request on the aws-amplify documentation is open : https://github.com/aws/aws-amplify/pull/633
I also faced the similar issues, It showed the default error message "Request failed with status code 400", instead of the message that is returned from API.
I logged the Error object and it did not show the response attribute in it. But we do have response attribute. I tried logging the Error.response and it did contain the response sent from the API.
Just figured out this by going through the 'Cancel API requests' Amplify docs.
From what I can see this is the contents of the error object returned by the API call:
Heres what I am doing to just print out the error, obviously you would do a lot more here but its a good start.
async uploadUser(state, payload) {
const promise = API.graphql({
query: createUser,
variables: { input: payload },
});
try {
await promise;
} catch (error) {
// Print out the actual error given back to us.
console.log(error.errors[0].message);
// If the error is because the request was cancelled we can confirm here.
if (API.isCancel(error)) {
// handle user cancellation logic.
console.log(error.message);
}
}
Hope that helps 😃

Resources