Proper error handling for Angular 2 http result [duplicate] - http

This question already has answers here:
Angular2 handling http response
(3 answers)
Closed 6 years ago.
I've been using the http error handling strategy used in the angular.io documentation:
getHeroes () {
return this.http.get(this._heroesUrl)
.map(res => <Hero[]> res.json().data)
.catch(this.handleError);
}
private handleError (error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
In some scenarios, instead of a JSON response I will receive a 204 status code (No Data). In this case, the error handler doesn't get invoked until failing to parse the result via res.json(), so the error passed to handleError is "error.json is not a function".
How can I interrogate the response stream to check for a 200 (OK) status code or a response header content-type of "application/json", and signal an error handler with a more relevant error message?

http .get('Some Url') .map(res => {
// If request fails, throw an Error that will be caught
if(res.statu != 200) {
throw new Error('This request has failed ' + res.status); } // If everything went fine, return the response
else {return res.json();
} })
This may help you.
This is just for understanding how to use the status from the response, you can modify according to your requirement.
Error is thrown only for non 200 code check this commit

Related

Changing the default exception message in Axios

When hitting an HTTP error, Axios only states the HTTP status code in the thrown exception message. I want the exception message to include the request URL, too.
I tried to implement what I want using the following interceptor:
axios.interceptors.response.use(
response => response,
error => {
throw `HTTP ${error.response.status} by ${error.request.url}`;
}
);
The error callback doesn't get triggered upon HTTP errors. Any ideas?
Try to use Promise.reject to replace throw.
The following code works for me. Tested in Chrome.
axios.interceptors.response.use(
function (response) {
return response;
},
function (error) {
return Promise.reject(`HTTP ${error.response.status} by ${error.response.config.url}`);
});
Also, you can simply catch the exception like -
let res = await axios.post(...)
.catch(error => {
console.log(error.response);
console.log(error.request);
});
You have access to all the error details as in interceptor.

Koa SSE "write after end"

I have been trying to implement an SSE stream with Koa for hours now but got the following error when trying to send a message to my client after initializing the connection.
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
Here's how I set up my SSE:
Client-side:
const source = new EventSource("http://localhost:8080/stream");
this.source.onmessage = (e) => {
console.log("---- RECEIVED MESSAGE: ", e.data);
};
// Catches errors
this.source.onerror = (e) => {
console.log("---- ERROR: ", e.data);
};
Server-side (Koa):
// Entry point to our SSE stream
router.get('/stream', ctx => {
// Set response status, type and headers
ctx.response.status = 200;
ctx.response.type = 'text/event-stream';
ctx.response.set({
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
// Called when another route is reached
// Should send to the client the following
ctx.app.on('message', data => {
ctx.res.write(`event: Test\n`);
ctx.res.write(`data: This is test data\n\n`);
});
});
The error comes when we call ctx.res.write once a message is received.
Why is my stream ended although nothing explicitly is doing it?
How may I send a message through the stream with Koa?
Koa is entirely promise based and everything is a middleware.
Every middleware returns a promise (or nothing). The middleware chain is effectively 'awaited' and once the middleware returns, Koa knows the response is done and will end the stream.
To make sure that Koa doesn't do this, you have to make sure that the chain of middlewares don't end. To do this, you need to return a promise that only resolves when you're done streaming.
A quick hack to demonstrate would be to return a promise that doesn't resolve:
return new Promise( resolve => { }});

Service Worker - TypeError: Request failed

I used service worker to cache the resource from the other domain. I get this error "TypeError: Request failed serivce-worker.js:12" I don't know why this error is occurring.
service-worker.js
var cacheNames=['v1'];
var urlsToPrefetch=['file from other domain'];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(cacheNames).then(function(cache) {
console.log('Service Worker: Caching Files');
cache.addAll(urlsToPrefetch.map(function (urlToPrefetch) {
console.log(urlToPrefetch);
return new Request(urlToPrefetch, {mode: 'no-cors'});
})).catch(function(error){
console.log(error);
});
})
);
});
self.addEventListener('fetch', function(event) {
console.log('Service Worker: Fetching');
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
This is a side-effect of dealing with opaque responses (those fetched with mode: 'no-cors'). Here's an excerpt from this longer answer:
One "gotcha" that developer might run into with opaque responses involves using them with the Cache Storage API. Two pieces of background information are relevant:
The status property of an opaque response is always set to 0, regardless of whether the original request succeeded or failed.
The Cache Storage API's add()/addAll() methods will both reject if the responses resulting from any of the requests have a status code that isn't in the 2XX range.
From those two points, it follows that if the request performed as part of the add()/addAll() call results in an opaque response, it will fail to be added to the cache.
You can work around this by explicitly performing a fetch() and then calling the put() method with the opaque response. By doing so, you're effectively opting-in to the risk that the response you're caching might have been an error returned by your server.
const request = new Request('https://third-party-no-cors.com/', {mode: 'no-cors'});
// Assume `cache` is an open instance of the Cache class.
fetch(request).then(response => cache.put(request, response));

handling server error response along with data in angular 2 using HTTP observable

This is regarding handling server response in angular2
As i understand,
1. server response code 200, 201 etc will make success response
2. while server response 400, 401, 500 etc will make error response
3. if response is success, then it will goto map function, from there we can return the data or modify it.
4. if response is error, then it will go to catch function, from there we will can return observable or throw the observable.
My question is if server returned error response code along with error data, then how to capture that data.
i.e suppose i am sending below data from server
success response
status: 200
msg: "successfully loggedin"
error response
status: 400
msg: "userid and password is wrong"
Here i am able to get or handle success data but not the error data,because in catch function, only error object is getting passed and that error object only contain response code from server, not the response data
return this.http.get('/login')
.map( (res: Response) => res.json().data )
.catch( (error: any) => {
return Observable.throw( new Error("error occured"+error.status));
})
Update:
don't put return in map and catch function.
Below is updated code
return this.http.get('/login')
.map( ( successRes: Response) => {
res.json().data
)}
.catch( ( errorRes: Response ) => {
Observable.throw( errorRes.json().data );
})
Original:
Actually solution was very simple, response data itself is attached to first argument, its just like normal response as in the case of success response.
Just needed to add json() call to response error object to convert the json to js object, something like this.
return this.http.get('/login')
.map( ( successRes: Response) => {
return res.json().data
)}
.catch( ( errorRes: Response ) => {
return Observable.throw( errorRes.json().data );
})
You don't have to .catch() it!
If your server sends the correct message, just subscribe that Observable!
yourLoginService.LogInFunction().subscribe(
successData => console.log(successData),
errData => console.log(errData)
);

Angular 2 RC5 http error handling

I am new in Angular 2, in my Angular 2 project I create API call service that return json data.
this._http.post(this.url, body, options)
.map(response => response.json())
.catch(this.handleError);
Let say this service return 401 Http Response unauthorized and I tried get the status error, so I can redirect to Login Page and show error message
.subscribe(
login => this.login=login,
error => this.errorMessage = <any>error);
}
but why response code did not throw as error, and only show result
Failed to load resource: the server responded with a status of 401 (Unauthorized) and end the task ?
when I debug the code, the result generated in this line code
this.invoke = function () {
try {
return zone.runTask(self, this, arguments);
}
finally {
drainMicroTaskQueue();
}
};
}
any suggestion ?
Thank You

Resources