I have a firebase function in which I manually throw an error with a status and message like this:
throw new functions.https.HttpsError('permission-denied', 'Token does not match');
The response I get from the server looks like this (using chrome dev console):
{"error":{"message":"Token does not match","status":"PERMISSION_DENIED"}}
But when I call the function like this, the error does not have a status in it (using AngularFire2):
try {
return await this.functions.httpsCallable<void, void>('testFunc')().toPromise();
} catch (e) {
console.log(e.name); // "Error"
console.log(e.message); // "Token does not match"
console.log(e.status); // undefined
}
Is there any way to get the status of it, because I would rather check for if(e.status == 'PERMISSION_DENIED') than if(e.message == 'Token does not match').
e is going to be a HttpsError object. As you can see from the API docs, it should have a property called code which is a FunctionsErrorCode object that contains the HTTP status code as a string that should match what you threw from the callable function. So I would expect e.code to be the string permission-denied.
Related
When fetching postcode from Postcode io API, I tried this error handling code:
async getCoord() {
const postcodeAPI = `http://api.postcodes.io/postcodes/dt12pbbbbbbbbb`;
let response;
try {
response = await fetch(postcodeAPI);
}
catch (e) {
console.log(e);
};
};
The fetch method returns a 404 error as postcode is invalid. In my understanding the try block should be tried and skipped and the error should be caught by the catch method, but instead I got this red 404 error in console:
which happens in the try block, and is the same as no error handling in the code. Why does this happen? Is it because this is browser default behaviour? Is there a way to improve the error handling here?
EDIT
What I wanted was the red console error to disappear and show my own error information instead, but the console error seems unavoidable.
Fetch API doesn't throw errors on any status code. It only throws errors on network failures, i.e. when it couldn't finish the request itself.
You can use response.ok to check if the request finished with 2XX status code.
async getCoord() {
const postcodeAPI = `http://api.postcodes.io/postcodes/dt12pbbbbbbbbb`;
let response;
try {
response = await fetch(postcodeAPI);
if (!response.ok) throw new Error('Request failed.');
}
catch (e) {
console.log(e);
};
};
You can also explicitly check the status code if you need:
if (response.status === 404) {
// handle 404
}
As for your question about logging 404 errors in the console, there's no way or need to avoid it. Whenever you make a request, it's being logged in the dev tools. But dev tools are just what they are called - tools for devs. You can safely assume your users won't look there and even if someone does, having 404 there is not the end of the world.
I wrote a function that keeps returning an Access-Control-Allow-Origin error. This is actually fine for me; I don't want to fix this. I just want to catch it so I can read its message in my program.
All the code that causes the error to be thrown is within my try block, and my catch block displays the error's string message. However, when I run the code, no error is caught, and the error shows up in red in the console. How do I catch this error and store its message?
try {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status < 400 && this.status >= 300) {
console.log('this redirects to ' + this.getResponseHeader("Location"));
} else {
console.log('doesn\'t redirect');
}
}
xhr.open('HEAD', $scope.suggLink, true);
xhr.send();
} catch(e) {
console.log('Caught it!');
console.log(e.message);
}
While browsers will log a more-detailed error message to the console, you can’t access that from your code. See https://bugs.chromium.org/p/chromium/issues/detail?id=118096#c5:
The details of errors of XHRs and Fetch API are not exposed to JavaScript for security reasons.
As far as the what specs actually require here, the Fetch spec is what defines the details of the “status message” to provide in case of an error — even if XHR is used instead of the Fetch API (the XHR spec references the Fetch spec). And for any network error or response blocked by the browser, the Fetch spec requires that the status message be “the empty byte sequence”:
A network error is a response whose status is always 0, status message is always the empty byte sequence, header list is always empty, body is always null, and trailer is always empty.
So all you can get back from any error you can catch is “TypeError: Failed to fetch” or such.
If you’re using XHR, all you have for handling an error is the onerror event handler:
xhr.onerror = function() { console.log("Error occurred but I dunno what exactly.")}
jquery version of above (sideshowbarker's) workaround for CORS error:
let sURL = 'https://www.mocky.io/v2/5185415ba171ea3a00704eed';
$.getJSON(sURL, function (json)
{
console.log('json from web-service ->', json);
})
.fail(function()
{
console.log("error - could not get json data from service");
});
I have this:
Meteor.methods({
'foo'() {
try{
...//some http.get
} catch (e) {
console.log(e); //-> { [Error: ETIMEDOUT] code: 'ETIMEDOUT', connect: true }
if(e.code === 'ETIMEDOUT') { throw e; }
}
}
});
So now i am on client:
Meteor.call('foo', function(error, result) {
if(error){
if(error.code === 'ETIMEDOUT') {
//this block is never reached.. why?
}
}
}
But it seems the error.code is not the same as on server (It seems like it's been changed to Internal Server Error). Why is this? And more important, how can i get my original (in this case timeout) error?
from the manual:
When you have an error that doesn’t need to be reported to the client,
but is internal to the server, throw a regular JavaScript error
object. This will be reported to the client as a totally opaque
internal server error with no details.
That is what you're seeing. Instead:
When the server was not able to complete the user’s desired action
because of a known condition, you should throw a descriptive
Meteor.Error object to the client.
Meteor.Error takes three arguments: error, reason, and details.
so you might do something like this:
if (e.code === 'ETIMEDOUT') {
let userMessage = 'The remote call timed out.';
let detail = `${userMessage}: ${JSON.stringify(e)}`;
console.error(detail);
throw new Meteor.Error('remote-call-timed-out', userMessage, detail);
}
The first argument, the "error" (i call it a "code"), is something you can program against on the client to take a specific action or internationalize the user message. that's what we do in our system. (and if the code is not found, we show the userMessage). the detail gets written to the server log and put into the browser console.log.
I have a function which use axios get method and on the promised returned I have added error handling to handle a situation when service I am trying to connect to has been disabled.
axios.get('/someurl')
.then(() => {
// this does not matter
})
.catch((err) => {
logger.error(TAG, 'postCreateVm', err);
return reply(Boom.forbidden(err.message));
});
When I use curl I can see the message, status of response is 403:
# curl -X GET localhost:3000/someurl
{
"message": "abort"
}
The problem is that when I try to access 'message' property i get nothing, but I know it's there! (I have tried to use err.response.data as well with no success also)
According to the documentation I should be able to access it: axios handling errors
What is the proper way to access this message?
I've looked at his code, and it appears the correct response is in the error, but in axios, settle.js masks it with a generic response. You can see the server response by logging the error object in your catch block as stringified JSON:
console.log('caught:::', JSON.stringify(response, null, 2))
So in my case, I fixed it by accessing the returned error as:
error.response.data.message
My catch function received the response property instead of error object. So, to access message I had use:
err.data.message
I have a node app that uses a cluster of child processes. I am trying to handle errors in these children.
Children communicate with the master when they have finished their task by sending a message with the result of their work. If they encounter a problem they send an error:
var error = new Error("I am sorry MASTER, I failed");
const isError = error instanceof Error;
console.log(`throwing new error: ${error} ${isError}`);
process.send( error );
From this I get a console output:
throwing new error: I am sorry MASTER, I failed true
I then handle this in master:
const isError = message instanceof Error;
console.log(`Message: ${message} ${isError}`);
if(message instanceof Error)
{
//handle error;
} else {
//process message;
}
From this console log I get the following:
Message: [object Object] false
When the message is sent using the send() function instanceof no longer works.
How can I tell in the master that the message sent is an Error? I don't want to change the error at all as I don't want to put any constraints on the code in the child process, I want to just be able to send an error.
Thanks
https://nodejs.org/api/process.html#process_process_send_message_sendhandle_options_callback
Note: This function uses JSON.stringify() internally to serialize the message.*
let foo = new Error("ai caramba¡");
let bar = JSON.stringify(foo);
console.log(bar); // {}
You can find more information in the SO question "Is it not possible to stringify an Error using JSON.stringify?".