Angular's subscribe not logging full error - javascript

I'm trying to log an error from a subscribe, but the error seems... incomplete?
I've never seen this kind of problem, nor could I find anything on Google. The code is the following:
this._http.post(this.urlPath, email).subscribe(
res => {
// stuff
},
err => {
console.log(err) // <- I need to log this
}
);
It works to an extent. When I open the browser's console, in order to check the error, what I get is this:
The thing is, it seems like there's missing information here. If I open the Network tab, the response for this same request looks like this:
As you can see, the real response has more information. I've tried using {observe: "response"}, but to no avail. I should note that if I try using fetch, the response comes complete, but I'd rather use HttpClient.
What is going on here?

When you receive a http error status code you can't access to the payload returned by the service by the same way that in a success case. Is like an special object.
But you can acccess to it doing some like this, using a pipe in your service and an error handler. This is a minimal example of it:
your.service.ts
...
handleError(error) {
return throwError(error.error);
}
return this.http.get ... the rest of your request.pipe(
catchError(this.handleError)
);
...
And where you consume your service, in err you can acces to full response that your error request contains.
...
, error => {
console.warn(error);
}
Or better than, you can throw the entire object to access to the error (response body) and the rest of params, like status code.

Related

Why does a GET request with fetch API log a server response error message into the browser console?

I am using the fetch-API to send a GET request to a Spring Boot backend. The request looks somewhat like this:
const response = await fetch(url);
if (response.status === 200) {
// do something
} else {
response.json().then(response => console.log(response));
}
In case that I send a valid request, i.e. the url passed into fetch() is valid, everything works fine. In case that I pass an invalid url into fetch(), however, two things appear to be happenning:
A serer response message is thrown:
My Spring Boot backend return a ResponseEntity with a custom error message as body. This error message is logged inside the else-block of the above code snippet:
While I do expect the second point to be happenning, I cannot explain the first. I don't understand why this server-response error is logged into my browser console. I do have a few catch-blocks inside my code, something like:
const response = await fetch(url).catch(error => console.log(error));
As far as I know, however, fetch only throws an error if a network connection error occurred or similar. A response code not equal to 200 does not result in fetch throwing an error. So, as I said, I don't know where this error message comes from and I was hoping that somebody does, maybe it is something generic to the fetch API that I just don't know?
I recommend using "try catch" to better capture errors.
If the response is positive and it's a json, use a "then" after the fetch.
try {
const response = await fetch(url).then(res => res.json());
// do something
} catch (e) {
console.error(e);
}
If you're getting a 400 error, check the api documentation to see if you're passing the parameter incorrectly. or if that is not the route

axios.post.then() is ignoring the then() part for some reason

I have this function...
function waterCalibrator() {
axios.post("http://localhost:3001/api/update-water", {
waterValue: props.moisture
}).then(function(response){
console.log("Water calibration worked")
console.log(response);
}).catch(function(error) {
console.log(error);
})
props.airValueObject.setWaterFlag(true);
props.airValueObject.setWaterValue(props.moisture);
}
Can anyone explain why then() is not ever triggered? I have no errors. It simply isn't triggering. Everything works except for this...
}).then(function(response){
console.log("Water calibration worked")
console.log(response);
}).catch(function(error) {
console.log(error);
})
server side looks like this...
app.post("/api/update-water", (req, res) => {
const waterValue = req.body.waterValue;
const sqlUpdateWater = "UPDATE user SET waterValue=? WHERE uid='j' ";
db.query(sqlUpdateWater, [waterValue], (err, result)=>{
console.log(`water is: ${waterValue}`)
})
})
You are getting a 204 status code, which means the request went through successfully but there is no content at all, hence you are trying to log nothing.
The HTTP 204 No Content success status response code indicates that the request has succeeded, but... The common use case is to return 204 as a result of a PUT request, updating a resource, without changing the current content of the page displayed to the user. If the resource is created, 201 Created is returned instead. If the page should be changed to the newly updated page, the 200 should be used instead.
You also need, as suggested in previous comments, open the dev console and check the status of the promise itself. This promise seems to be successful.
If this answer helps solving the issue, consider accepting the answer or upvoting it. Thanks.

Can We Explicitly Catch Puppeteer (Chrome/Chromium) Error net::ERR_ABORTED?

Can we explicitly and specifically catch Puppeteer (Chromme/Chromium) error net::ERR_ABORTED? Or is string matching the only option currently?
page.goto(oneClickAuthPage).catch(e => {
if (e.message.includes('net::ERR_ABORTED')) {}
})
/* "net::ERROR_ABORTED" occurs for sub-resources on a page if we navigate
* away too quickly. I'm specifically awaiting a 302 response for successful
* login and then immediately navigating to the auth-protected page.
*/
await page.waitForResponse(res => res.url() === href && res.status() === 302)
page.goto(originalRequestPage)
Ideally, this would be similar to a potential event we could catch with page.on('requestaborted')
I'd recommend putting your api calls and so in a trycatch block
If it fails, you catch the error, like you are currently doing. But it just looks a bit nicer
try {
await page.goto(PAGE)
} catch(error) {
console.log(error) or console.error(error)
//do specific functionality based on error codes
if(error.status === 300) {
//I don't know what app you are building this in
//But if it's in React, here you could do
//setState to display error messages and so forth
setError('Action aborted')
//if it's in an express app, you can respond with your own data
res.send({error: 'Action aborted'})
}
}
If there are not specific error codes in the error responses for when Puppeteer is aborted, it means that Puppeteer's API has not been coded to return data like that, unfortunately :')
It's not too uncommon to do error messages checks like you are doing in your question. It's, unfortunately, the only way we can do it, since this is what we're given to work with :'P

Clarifying "400 - Bad Request"

I am triggering a bad request on purpose from my backend. The backend using express is answering properly as expected with:
[...]
.catch((error) => {
res.statusCode = 400;
res.json({
msg: "This is some error",
err: error,
});
});
My question is: Is the 400 always showing up in browser console? I thought I handled the error the right way.
And why do I have to retrieve the data in the frontend with
// 400:
function (data) {
var data = data.responseJSON.msg);
}
instead of (similar to 200:)
// 400:
function (data) {
var data = data.msg);
}
I am just wondering, if I do something wrong.
Thanks for any advice
When fetching data asynchronously, any response other than a 2** response code gets handled by a .catch block. So any other response whether it be 4** or 5** gets caught by the catch block and for that reason if you're using a library like Axios or the likes the response from the backend will be in the error.response or data.response in your case.
I wasn't aware of what you're using to carry out the asynchronous fetching of data i.e. Fetch Api so my answer is a generic response and also is the above code complete?
In my experience any error from whatever weither it be am asynchronous call that generates an error always gets logged to the console, but you can from the front end handle those errors in the catch block
The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property or in your case the .responseJSON
By catching your error with an catch block .catch() or if you using async / await you should, usually, wrap the code inside of an try / catch to catch the error otherwise it will always output this red error in the console

Angular 2 Http get not triggering

As said in the title, nothing is happening when I subscribe to my observable. There is no error in the console or during the build. Here is my code :
My service
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25').map(
(res: Response) => {
return res.json();
});
}
My component
ngOnInit() {
this.planifRequestService.getBlueCollars().subscribe(
data => {
this.blueCollars = data;
console.log('Inner Blue Collars', this.blueCollars);
},
err => console.log(err)
);
console.log('Value BlueCollars : ', this.blueCollars);
}
So the second console.log is triggering with "Value BlueCollars : Undefined", and the log in my subscribe is never showed. As well, I can't see the request sent in the Networt tab of Chrome.
So I tried to simplify everything with the following code :
let response: any;
this.http.get('myUrl').subscribe(data => response = data);
console.log('TestRep: ', response);
Same problem here, no error, response is undefined. It seems the subscribe is not triggering the observable. (The URL is correct, it is working on my swagger or with postman.)
I'm on Angular 2.4.9
Edit
So I tried to copy/past the code of my request on a brand new project, everything is working fine. The request is triggered and I can get the JSON response correctly. So there is something maybe on the configuration of my project that is forbiding the request to trigger correctly.
Ok just found what was going on. I am using a fake backend in order to try my login connexions that is supposed to catch only specified URL. However for wathever raison it was catching all the requests, so that explain everything. Thx for your help everybody.
Try adding a catch block to your service code:
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25')
.map(
(res: Response) => {
return res.json();
})
.catch(err => Observable.throw(err))
}
Don't forget to
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';`
I imagine this will result in the error that'll give you an idea where your code is going wrong.
The reason the console.log outside the subscribe call is undefined is because the subscribe/http call is happening asynchronously and so, in effect, the order (in time!) the code is running is:
1) the observable is subscribed to (and then waits for a response)
2) the outer console log runs with blueCollars undefined
3) when the response (or error) comes back from the http request (potentially after several seconds), only then will the inner assignment of this.blueCollar = data happen (and the inner console log), OR an error will get logged
Apart from that the subscribe code looks fine...!

Categories

Resources