Error handling middleware in node js backend:
app.use((error, req, res, next) => {
console.log(error);
const status = error.statusCode || 500;
const message = error.message;
const data = error.data;
res.status(status).json({ message: message, data: data });
});
I have the following try catch block from my app:
userLogin() {
//axios vue instance
this.$http
.post("/auth/signup", this.formData)
.then((res) => {
// res.status == 201 ? (this.formData = {}) : "";
console.log(res);
})
.catch((err) => {
console.log(err);
console.log(err.data.data);
console.log(err.data.msg);
});
},
The output of the above catch block are as follows:
[![enter image description here][2]][2]
While my rest api sends the message in following format (seen on Network > Preview)
{
message: "Validation failed.",
…
}
data: [{
location: "body",
param: "email",
value: "test#test.com",
msg: "E-Mail address already exists!"
}]
message: "Validation failed."
I want to access the data array and print its content.
How can I access data ?
We can catch custom error message:
userLogin() {
this.$http
.post("/auth/signup", this.formData)
.then((res) => {
// res.status == 201 ? (this.formData = {}) : "";
console.log(res);
})
.catch((err) => {
console.log(err.response.data.data);
});
},
Axios stores the actual response in its data prop (unrelated to your API's data property in the response contents), so you could access your data property like this:
this.$http.post('/auth/signup', this.formData)
.then((res) => {
const apiResponse = res.data
console.log(apiResponse.data) // logs `data` property from API response contents
})
.catch((err) => {
/*...*/
})
More readable format
async userLogin() {
try {
// Call the server
const {data} = await this.$http.post("/auth/signup", this.formData);
// If you want message
let message = data.message;
// If you want the data object, ex data: [{location: "body"....}]
let dataObject = data.data;
} catch (e) {
// In case of error
console.log(err.response);
}
};
Related
This question already has answers here:
loging the response.json() inside the then() method before returning the response.json() promise
(1 answer)
JavaScript fetch - Failed to execute 'json' on 'Response': body stream is locked
(11 answers)
Closed 6 months ago.
I am trying to figure out what change I need to make to my flow where I am triggering a post call and on success return to run another fetch call followed by a 3rd party generated redirect (Stripe). At the moment I am receiving an error message at const session = await response.json()
with the message:
Failed to execute 'json' on 'Response': body stream already read
and I'm not sure how to refactor my code to be able to handle this issue. Can anyone point to what is wrong with my current setup and the rules I might be breaking?
const signUp = (e) => {
e.preventDefault();
if (password === passwordConfirmation) {
axios
.post(
"/api/auth/signup/",
{ email, password, passwordConfirmation },
{
headers: {
"Content-Type": "application/json",
},
withCredentials: true,
}
)
.then((res) => {
const data = res.data;
setUser(data.user);
// Set the error message
if (data.message.status === "error") {
console.log("Error present");
setMessage(data.message);
}
return data.message.status;
})
.then(async (serverMessage) => {
// On successful sigin, redirect to /api/stripe/checkout-session/
if (serverMessage !== "error") {
// Get Stripe.js instance
const stripe = await stripePromise;
const response = await fetch("/api/stripe/checkout-session/", {
method: "POST",
});
console.log(`response: ${response.json()}`);
const session = await response.json();
console.log(`session: ${session}`);
// When the customer clicks on the button, redirect them to Checkout.
const result = await stripe.redirectToCheckout({
sessionId: session.sessionId,
});
// router.push('/api/stripe/checkout-session/')
// router.push('/app/feed/')
}
})
.catch((err) => {
console.log(err);
console.log(err.request);
console.log(err.message);
});
} else {
setMessage({
status: "error",
body: "Passwords do not match. Please try again.",
});
}
};
Do not call .json() twice.
change
console.log(`response: ${response.json()}`);
const session = await response.json();
to
const session = await response.json();
console.log(`response: ${session}`);
you can only read body stream once :) Try this
const signUp = (e) => {
e.preventDefault();
if(password === passwordConfirmation){
axios.post('/api/auth/signup/', { email, password, passwordConfirmation }, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true
}).then((res) => {
const data = res.data;
setUser(data.user)
// Set the error message
if(data.message.status === 'error'){
console.log('Error present')
setMessage(data.message)
}
return data.message.status
}).then(async (serverMessage) => {
// On successful sigin, redirect to /api/stripe/checkout-session/
if (serverMessage !== 'error'){
// Get Stripe.js instance
const stripe = await stripePromise;
const response = await fetch('/api/stripe/checkout-session/', { method: 'POST' });
const responseBody = await response.json()
console.log(`response: ${responseBody}`);
const session = responseBody;
console.log(`session: ${session}`);
// When the customer clicks on the button, redirect them to Checkout.
const result = await stripe.redirectToCheckout({
sessionId: session.sessionId,
});
// router.push('/api/stripe/checkout-session/')
// router.push('/app/feed/')
}
}).catch((err) => {
console.log(err)
console.log(err.request)
console.log(err.message)
})
} else {
setMessage({
'status': 'error',
'body': 'Passwords do not match. Please try again.'
})
}
}
I'm trying to catch the error this error message from my Rest controller in spring
#GetMapping
public List<Student> getAllStudent() {
throw new IllegalStateException("Opps can not get all students");
// return studentService.getAllStudents();
}
The error is catch in react this way, what I'm trying to do is to show in the console the Error message
import fetch from "unfetch";
const checkStatus = (response) => {
if (response.ok) {
return response;
} else {
let error = new Error(response.statusText);
error.response = response;
response.json().then((e) => {
error.error = e;
});
return Promise.reject(error);
}
};
export const getAllStudents = () =>
fetch("http://localhost:1020/api/students").then(checkStatus);
And then is consume by this method to show it in the console
const fetchAllStudents = () => {
this.setState({
isFetching: true,
});
getAllStudents()
.then((res) =>
res.json().then((students) => {
console.log(students);
this.setState({
students,
isFetching: false,
});
})
)
.catch((error) => {
console.log(error.error.message);
// const message =error.error.message;
// errorNotification(message,message)
this.setState({
isFetching: false,
});
});
};
The problem is that I get is that "message" is undefined I want to log "Opps can not get all students" in the console:
Add this line to your application.properties file:
server.error.include-message=always
And try throwing ResponseStatusException, so that you give a HTTP Status, together with the message, and not just 500 Server Error.
Like this:
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Your Message...");
I am trying to wright an object to a db file using JSON server; however, the JSON server keeps giving the error: TypeError: Cannot read property 'id' of undefined.
I can successfully read for the file using Fetch, its just POST that I'm having this trouble with. Any ideas?
//this is the function where I perform the POST
const handleSubmit = (e) => {
e.preventDefault();
setSubmitted('t');
setIsPending(true);
const arg = { filename, trialId, hash, location, author, submitted };
fetch('http://localhost:8000/args/', {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(arg)
}).then(() => {
console.log('new file added');
})
};
//This is my current db file:
{
"args": [
{
"filename": "Accelerometer",
"trialId": "01",
"hash":"",
"author": "",
"location": "IPFS",
"submitted": "f"
}
]
}
// This is my fetch that works that I use to read from the db page.
setTimeout(() => {
fetch('http://localhost:8000/args', { signal: abortCont.signal })
.then(res => {
//check response for error
if (!res.ok) {
throw Error('Error when fetching data');
}
return res.json();
})
.then(data => {
setArgs(data);
setIsPending(false);
setError(null);
})
.catch(err => {
if (err.name === 'AbortError') {
console.log('fetch aborted');
} else {
setError(err.message);
setIsPending(false);
}
})
}, 1500);
// This is the function Function.createID in the server that seems to be having an issue.
function createId(coll) {
const _ = this;
const idProperty = _.__id();
if (_.isEmpty(coll)) {
return 1;
} else {
let id = _(coll).maxBy(idProperty)[idProperty]; // Increment integer id or generate string id
return _.isFinite(id) ? ++id : nanoid(7);
}
}
I'm doing requests to my API server to authenticate a user, that's not the problem. The problem is that I don't know why my async function doesn't return anything, and I get an error because the data that I want from this function is undefined.
Don't worry if the error management is ugly and in general I can do this better, I'll do that after fixing this problem.
Utils.js class
async Auth(username, password) {
const body = {
username: username,
password: password
};
let req_uuid = '';
await this.setupUUID()
.then((uuid) => {
req_uuid = uuid;
})
.catch((e) => {
console.error(e);
});
let jwtData = {
"req_uuid": req_uuid,
"origin": "launcher",
"scope": "ec_auth"
};
console.log(req_uuid);
let jwtToken = jwt.sign(jwtData, 'lulz');
await fetch('http://api.myapi.cc/authenticate', {
method: 'POST',
headers: { "Content-Type": "application/json", "identify": jwtToken },
body: JSON.stringify(body),
})
.then((res) => {
// console.log(res);
// If the status is OK (200) get the json data of the response containing the token and return it
if (res.status == 200) {
res.json()
.then((data) => {
return Promise.resolve(data);
});
// If the response status is 401 return an error containing the error code and message
} else if (res.status == 401) {
res.json()
.then((data) => {
console.log(data.message);
});
throw ({ code: 401, msg: 'Wrong username or password' });
// If the response status is 400 (Bad Request) display unknown error message (this sould never happen)
} else if (res.status == 400) {
throw ({ code: 400, msg: 'Unknown error, contact support for help. \nError code: 400' });
}
})
// If there's an error with the fetch request itself then display a dialog box with the error message
.catch((error) => {
// If it's a "normal" error, so it has a code, don't put inside a new error object
if(error.code) {
return Promise.reject(error);
} else {
return Promise.reject({ code: 'critical', msg: error });
}
});
}
Main.js file
utils.Auth('user123', 'admin')
.then((res) => {
console.log(res); // undefined
});
Your Async function must return the last promise:
return fetch('http://api.myapi.cc/authenticate', ...);
or await the result and return it:
var x = await fetch('http://api.myapi.cc/authenticate', ...);
// do something with x and...
return x;
Notice that you don’t need to mix promise syntax (.then) with await. You can, but you don’t need to, and probably shouldn’t.
These two functions do exactly the same thing:
function a() {
return functionReturningPromise().then(function (result) {
return result + 1;
});
}
async function b() {
return (await functionReturningPromise()) + 1;
}
await is not to be used with then.
let data = await this.setupUUID();
or
let data=null;
setupUUID().then(res=> data = res)
I would try something like this:
const postReq = async (jwtToken) => {
const body = {
username: username,
password: password,
};
try {
const res = await fetch('http://api.myapi.cc/authenticate', {
method: 'POST',
headers: { "Content-Type": "application/json", "identify": jwtToken },
body: JSON.stringify(body),
})
if (res) {
if (res.status == 200) {
return res.json();
} else if (res.status == 401) {
const data = res.json();
console.log(data.message)
throw ({ code: 401, msg: 'Wrong username or password' });
} else if (res.status == 400) {
throw ({ code: 400, msg: 'Unknown error, contact support for help. \nError code: 400' });
}
}
} catch (err) {
console.error(err)
}
};
const Auth = async (username, password) => {
const jwtData = {
"origin": "launcher",
"scope": "ec_auth"
};
try {
const req_uuid = await this.setupUUID();
if (req_uuid) {
jwtData["req_uuid"] = req_uuid;
const jwtToken = jwt.sign(jwtData, 'lulz');
return await postReq(jwtToken);
}
} catch (err) {
console.error(err);
};
}
I'm trying to send some data from a React form to my Express back end. To do this I'm using fetch where I'm trying to send some variable data from react. I'm console logging the data before running the fetch to see if it is there, console log can see the data.
My error states
[0] (node:2966) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'message' of undefined
So it seems like my Express back end can't see the variable data.
How I'm sending the data from react
handleSubmit = async e => {
e.preventDefault();
console.log("Submit was pressed!");
if (this.state.email === "") {
}
const { name } = this.state;
const query = this.state.query;
const subject = "kontakt fra nettside";
const message = { name, query };
console.log(message.name, message.text, "data is");
fetch(
"http://localhost:5000/api/email", variabler
{
method: "POST",
cache: "no-cache",
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true,
content_type: "application/json"
},
body: JSON.stringify(message, subject)
}
); //.then(response => response.json());
};
My file for retrieving the data from the front end in Express
const emailConfig = require("./emailConfig")();
const mailgun = require("mailgun-js")(emailConfig);
exports.sendEmail = (recipient, message, attachment) =>
new Promise((resolve, reject) => {
const data = {
from: "Test <test#test.no>", // Real email removed from this post
to: recipient,
subject: message.subject,
text: message.query,
inline: attachment,
html: message.html
};
mailgun.messages().send(data, error => {
if (error) {
return reject(error);
}
return resolve();
});
});
and sendMail.js
const express = require("express");
const sendMail = express.Router();
const emailUtil = require("./emailUtil");
const { sendEmail } = emailUtil;
sendMail.post("/", async (req, res, next) => {
// const { recipient, message } = req.body;
console.log("Request mottatt");
const recipient = "test#test.no";
const message = req.body.message;
try {
await sendEmail(recipient, message);
res.json({ message: "Your query has been sent" });
console.log("Message has been sent");
await next();
} catch (e) {
await next(e);
console.log("nah", e);
}
});
module.exports = sendMail;
I can't figure out where the error is, any ideas? :)