how to access exceptions thrown by Nestjs from frontend? - error-handling

I am building backend API with Nestjs and I want to access exeptions from frontend
this is a simple example from login endpoint when user enters non-existent email :
const user = await this.userModel.findOne({ email });
if (!user) {
throw new NotFoundException('email does not exist .');
}
now when I send request from my Nextjs application like this :
await axios
.post(`http://127.0.0.1:5000/user/login`, {
email: values.email,
password: values.password,
})
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log("Login catched an error : ", error);
});
I get the NotFoundException as error:
now I want to get the status of this error (404 in this case),is it possible ?

It's an AxiosError, so you should be able to access error.response.status as shown in Axios's documentation

Related

Getting error "FirebaseError: Messaging: We are unable to register the default service worker." setting up messaging with Sveltekit

Full error message
FirebaseError: Messaging: We are unable to register the default service worker. Failed
to register a ServiceWorker for scope ('http://localhost:3000/firebase-cloud-messaging-
push-scope') with script ('http://localhost:3000/firebase-messaging-sw.js'): A bad HTTP
response code (404) was received when fetching the script. (messaging/failed-service-
worker-registration).
at it.<anonymous> (window-controller.ts:166:27)
at tslib.es6.js:100:23
at Object.throw (tslib.es6.js:81:53)
at i (tslib.es6.js:72:64)
Contents of src/service-worker.js
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-app.js")
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-messaging.js")
firebase.initializeApp({
apiKey: '...',
authDomain: '...',
projectId: '...',
storageBucket: '...',
messagingSenderId: '...',
appId: '...',
})
const messaging = firebase.messaging()
Contents of src/firebase-messaging-sw
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-app.js")
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-messaging.js")
firebase.initializeApp({
'messagingSenderId': "..."
})
const messaging = firebase.messaging()
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('../firebase-messaging-sw.js')
.then(function (registration) {
console.log('Registration successful, scope is:', registration.scope);
}).catch(function (err) {
console.log('Service worker registration failed, error:', err);
});
}
contents of src/jsconfig.json
"include": [
"src/**/*.d.ts",
"src/**/*.js",
"src/**/*.svelte",
"src/firebase-messaging-sw.js"
]
method that's calling firebase-messaging
messaging
.requestPermission() //It takes permission from user whether website can send notifications.
.then(res => {
console.log('Notification permission granted.', res)
if (messaging.getToken()) {
// THIS PROMISE SHOWS "pending" WITH STATE "rejected".
console.log('Token will come.', messaging.getToken())
}
return messaging.getToken()
})
.then(token => {
console.log(`token`, token)
})
.catch(error => {
// ERROR COMES FROM HERE
console.log('error under got token.', error)
})
.catch(function (err) {
errorElement.innerHTML = ErrElem.innerHTML + '; ' + err
console.log('Unable to get permission to notify.', err)
})
As a "throwing it against the wall to see what sticks", firebase-messaging-sw.js was added to jsconfig.json.
Chrome network tab shows firebase-messaging-sw as "pending", size "0 bytes".
Basically, it looks like this file is being missed. The serviceworker does it's job, and then when firebase comes back looking for this script in the root of the project, it either can't or won't find it.
How do I setup so that firebase can find this script?
You need to add empty firebase-messaging-sw.js file to your [YOUR_PROJECT]/public folder.
The goal is to have firebase-messaging-sw.js file straight in [YOUR_PROJECT]/dist folder for firebase to be able to fetch it from server.
Svelte is automatically copying files from public to dist while building the app.
I placed both scripts at the static folder and it worked in localhost at least

Call Nextjs API from within Netlify function

I got a serverless Netlify function like this:
exports.handler = async function(event, context) {
return {
statusCode: 200,
body: JSON.stringify({message: "Hello World"})
};
}
When called by this url <site-name>/.netlify/functions/helloworld
I do get the message {"message":"Hello World"}
I also got a pages/api/mailingList.js Nextjs API endpoint:
const axios = require('axios');
export default async function handler(req, res) {
//console.log(req.query.mail);
if (req.method === "PUT") {
axios
.put(
"https://api.sendgrid.com/v3/marketing/contacts",
{
contacts: [{ email: `${req.query.mail}` }],
list_ids: [process.env.SENDGRID_MAILING_LIST_ID],
},
{
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`,
},
}
)
.then((result) => {
res.status(200).send({
message:
"Your email has been successfully added to the mailing list. Welcome 👋",
});
})
.catch((err) => {
res.status(500).send({
message:
"Oups, there was a problem with your subscription, please try again or contact us",
});
console.error(err);
});
}
}
This mailing list API endpoint, do work when using curl from the terminal with PUT as the method:
curl -X PUT -d mail=helloworld#gmail.com https://netlify.app/api/mailingList
The API endpoint also work from the URL (/api/mailingList?mail=helloworld#gmail.com) when removing the if (req.method === "PUT") { part from the mailingList.js
However, I am NOT able to get the API endpoint to be called from within the Netlify function.
(Preferably the mailingList API should be possible to call multiple times with different mailing list IDs from the Netlify function helloworld.js based on different logic /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
To get the API endpoint to be called at all, from the function, I have tried adding a axios call from the helloworld.js to mailingList.js like this
const axios = require('axios');
exports.handler = async function(event, context) {
const mail = "helloworld#gmail.com";
// add to mailinglist
axios
.put("/api/mailingList?mail="+mail)
.then((result) => {
if (result.status === 200) {
toast.success(result.data.message);
}
})
.catch((err) => {
console.log(err);
});
}
This result in the following error from the browser: error decoding lambda response: invalid status code returned from lambda: 0
(I do not get any error msg from the Netlify log, either helloworld.js or mailingList.js)
Clearly, there is something wrong with how I call the mailigList.js from helloworld.js. Would greatly appreciate if some one could give me some advice and show me what I am doing wrong.
How can I call the API endpoint (mailigList.js) from within the Netlify function helloworld.js? (Preferably multiple times with different mailing list IDs: /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
Found the solution in this article: https://travishorn.com/netlify-lambda-functions-from-scratch-1186f61c659e
const axios = require('axios');
const mail = "helloworld#gmail.com";
exports.handler = (event, context, callback) => {
axios.put("https://<domain>.netlify.app/api/mailingList?mail="+mail)
.then((res) => {
callback(null, {
statusCode: 200,
body: res.data.title,
});
})
.catch((err) => {
callback(err);
});
};

Login With React Native using Asyncronous storage

I am implementing login in React Native using Asynchronous storage. Here, when users login successfully, i keep the user object in the Asynchronous storage then i access this information to get the Authentication Key for my API request anytime I want to do a request.
When I login and information is stored in the Asynchronous storage, the current app session fails to get the just stored information hence all my authenticated request fails in this session. When I close the app and restart, I can successfully get the information from the Async storage stored in the previous session and make successful authenticated request.
I do not know what I am missing out in my code as I believe I need to refresh or reload the app internally after a successful login but I do not know how to do this in React Native. Any information or help is needed. Here is my Login code.
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem(USER_DATA, JSON.stringify(data)).then(val => {
console.log('just before reload in login')
Actions.menu(); //this solves the after login problem as it goes to the next page only after a successful AsyncStorage save
this.setState({ procesing: false });
})
.catch(err => {
this.setState({ procesing: false, error: "Couldn't log you in! Please try again" });
//console.log("\nCouldn't save to AsyncStorage: " + err + "\n");
});
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
After I have login, my request looks like ;
//for making a post request
post: (url,body) => {
return fetch(url+'?access-token='+this.state.user.auth_key, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
//'Autorization': 'Bearer token2'
},
})
but the user object is gotten from the Async storage as
getUser(){
return AsyncStorage.getItem("USER_DATA").then(value => {
if(JSON.parse(value) == null) {
return false;
} else {
return JSON.parse(value)
}
});
},
Any Information, Ideas, proposed solutions are highly welcome
If you are receiving the information correctly, you can pass the information to the next screen or use the asynchronous repository as it is now.
If use navigation
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
this.setState({ procesing: false });
this.navigation.navigate("LoginScreen",{data: JSON.stringify(data) })
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
this.state={
data : this.props.navigation.state.params.data
}
If use AsyncStorge
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem("USER_DATA", JSON.stringify(data));
this.setState({ procesing: false });
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
async componentDidMount() {
let data = await AsyncStorage.getItem("USER_DATA")
}

Difficulty registering callback url with IBM watson speech-to-text npm module

I'm trying to register a callback url for the IBM speechToText service, using express, and I keep getting a 400 response when I call speechToText.registerCallback.
I've already ensured that the url exists and is providing responses as expected via Postman. I also know that my SpeechToText service has correct credentials.
I'm not seeing the 'challenge_string' logged when I call the endpoint using registerCallback.
router.get('/callback', (req,res,next) => {
console.log(req.query.challenge_string);
return res.status(200);
});
router.post('/newStream', (req,res) => {
var speechToText = new SpeechToTextV1({
username: <my_username>,
password: <my_password>,
url: 'https://stream.watsonplatform.net/speech-to-text/api/'
});
const registerCallbackParams = {
callback_url: 'http://127.0.0.1:8080/callback',
user_secret: 'ThisIsMySecret',
};
speechToText.registerCallback(registerCallbackParams)
.then(registerStatus => {
console.log(JSON.stringify(registerStatus, null, 2));
})
.catch(err => {
console.log(registerCallbackParams);
console.log('error:', err);
});
}```
It seems like the hostname in your callback url is 127.0.0.1, that is not a public hostname, but the address of the loopback interface.

404 error on post request in ec2 server

I deployed my mean stack project to amazon ec2 instance and i tried to login and it returns me 404 error (Cannot POST /api/user/login). Both the client side and server side code is inside the same project. When i run the project from localhost it works fine. What could be the issue ? Thanks.
Edit : Code snipped added
From controller
var credentials = {
email : $scope.user.email,
password : $scope.user.password
};
User.login(credentials)
.then(function (response) {
// Administrator. Redirect to /admin.html page
if($cookies.get('userType') == 0) {
$location.path('/admin');
}
console.log("From controller "+ response);
})
.catch(function(error) {
console.log(error);
})
From service
$http({
method : 'POST',
url : '/api/user/login',
data : data
})
.success(function (data, status, headers, config) {
object = JSON.parse(Util.toObject(data));console.log(object._id);
$cookies.put('userType', object['status']); // 0 for admin
$cookies.put('email', object.email); // store the email for session.
console.log(object['status'] + ' ' + object.email);
$('#loginModal').hide();
deffered.resolve(Util.toObject(data));
})
.error(function (data, status, headers, config) {
console.log("Error in Login "+ status);
deffered.reject(data);
})
BE route
app.use('/api/admin', require('./admin'));
Inside admin folder, index.js file
router.post('/login', controller.login);
controller.login file
exports.login = function(req, res) {
console.log(req.body);
User.find(req.body, function(err, data) {
if (err) {
console.log(' Error in finding the data .. ');
}
else {
console.log(' Data found in login ' + JSON.stringify(data));
res.status(200).json(data);
}
});
};
Found the issue in the end. I added '/' at the end of each API endpoint and it worked.