How to catch node.js http error on nonexistent host? - http

when I'm trying to use the http module to access nonexistent host, like this:
requestToRemote = http.createClient(80, 'fjasdfhasdkfj.vvvxcz').request(
method,
path,
headers
);
But I get the following error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: getaddrinfo ENOENT
at errnoException (dns.js:31:11)
at Object.onanswer [as oncomplete] (dns.js:140:16)
I'd like to catch this error, so I've tried try/catch and setting the error listeners of a bunch of request properties, but none of if worked. How can I catch the error?

Looks like the error is thrown from http.Client, not the request. How about something like:
var site = http.createClient(80, host);
site.on('error', function(err) {
sys.debug('unable to connect to ' + host);
});
var requestToRemote = site.request(...);
FYI, http.createClient has been deprecated -- the following should work using the get convenience method:
http.get({host: host}, function(res) {
...
}).on('error', function(e) {
console.log("Got error: " + e.message);
});

you could try and resolve the host using the dns module before running your code.
http://nodejs.org/docs/latest/api/dns.html#dns.resolve

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.

Apollo Network (Bad Request) error not caught in apollo-link-error

Sending a mutation with a bad set of variables (on purpose in this case) results in errors being thrown in the console, and the apollo-link-error link not picking up the error. Additionally, the mutation loading state is stuck as 'loading' and not error object comes through.
Through a debugging session, I fount that the zen-observable global error handling picks up an error thrown in the error-link's "next" function, because 'result' is not defined
pasted the apollo-link-error code that has the observable wrapped in a try catch, but the catch at the bottom here is not the catch that gets hit when if (result.errors) throws a 'nullpointer' because result in undefined.
try {
sub = forward(operation).subscribe({
next: function (result) {
// result is undefined, throwing an error
if (result.errors) {
retriedResult = errorHandler({
graphQLErrors: result.errors,
response: result,
operation: operation,
forward: forward,
});
if (retriedResult) {
retriedSub = retriedResult.subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
return;
}
}
observer.next(result);
},
error: function (networkError) {
retriedResult = errorHandler({
operation: operation,
networkError: networkError,
graphQLErrors: networkError &&
networkError.result &&
networkError.result.errors,
forward: forward,
});
if (retriedResult) {
retriedSub = retriedResult.subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
return;
}
observer.error(networkError);
},
complete: function () {
if (!retriedResult) {
observer.complete.bind(observer)();
}
},
});
} // the error is NOT caught here
catch (e) {
errorHandler({ networkError: e, operation: operation, forward: forward });
observer.error(e);
}
```
Link definition:
```javascript
export const client = new ApolloClient({
link: ApolloLink.from([
onError((errors) => {
console.log('errors in link!', errors);
handleServerError(errors);
}),
new MeteorAccountsLink(),
new HttpLink({
uri: '/graphql',
}),
]),
cache: new InMemoryCache(),
});
Edit:
The request in the browser does show a response with an error object with the graphQlErro of shape {errors: [{..}]} which is strange that it's not coming into the 'result' in the link.
Edit 2:
It looks like Meteor is picking up the error thrown in the http link prior to the error posted above, which might be why "result" is undefined. Writing a custom link to polyfill the missing 'result' so the app will at least work.
It seems like an issue with Meteor swallowing the errors. fixed make making a polyfill link to at least not break the js in the mutation complete function and show a general error.
const stupidMeteorErorrPolyfill = new ApolloLink((operation, forward) => forward(operation).map(data => data || { errors: [{ message: '! Empty response in gql links, see graphql.js and network tab' }] }));

Firebase authWithCustomToken throwing an error instead of calling callback?

I am following the example in the docs:
ref.authWithCustomToken(authToken, function(error, authData) {
if (error) {
console.log("Authentication Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
If I pass an invalid token to authWithCustomToken (e.g. authToken is undefined) , it throws an Error, rather than passing an error code to the callback. In other words, neither console.log is executed, but this error is thrown:
First argument must be a valid credential (a string).
Wrapping it in try catch solves the problem easily enough, but I didn't see any mention in the docs. Is it the intended behaviour?
In my use-case the token is passed through a url, so an undefined parameter is a possible error condition.
From firebase-debug.js:
if (!goog.isString(cred)) {
throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid credential (a string).");
}
What probably happened:
You passed a non-string value as authToken so the error not happened in the Firebase (server) side, it happened in the client side (your side) so it will be not reported on the callback function but as Javascript exception in your code.
Possible workaround (I don't know why, but if you want)
If you want to pass a variable as authToken and it could not be a string, and you still want to get the "Wrong credentials" error, instead of type validation, then you need to force string conversion using:
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
var numberAuthToken = 212312312312312; // number
var stringAuthToken = String(numberAuthToken);
ref.authWithCustomToken(stringAuthToken, function(error, authData) {
if (error) {
console.log("Authentication Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
But it not makes sense for me. :)

How do I retrieve the error message thrown by Future from the server to the client?

Inside my server, I that checks some data from the database and throws an error when it's not valid. I have it like so:
//SERVER CODE:
Meteor.methods({
send: function (prefix, number, content) {
Future = Npm.require('fibers/future');
var future = new Future();
//do some validation
myReference.doSomething({
number: number,
content: content
}, function(error) {
if(error) {
future.throw("Cannot send at this time.");
} else {
future.return("SUCCESS");
}
});
return future.wait();
}
});
In the client side, I would like to get the message "Cannot send at this time." inside future.throw("Cannot send at this time.");. Hopefully I could show it inside an alert. How do I do that?
Currently, this is what I'm trying and I keep getting some undefined error.
//CLIENT CODE
Meteor.call("send", prefix, number, content, function(err, result) {
if(err) {
console.log(err);
alert(err);
} else {
console.log("SUCCESSFULLY SENT. ", result);
}
});
This is the error I get when trying to get the error message:
errorClass: Internal server error [500]
{
error: 500,
reason: "Internal server error",
details: undefined, message: "Internal server error [500]",
errorType: "Meteor.Error"…}
details: undefined
error: 500
errorType: "Meteor.Error"
message: "Internal server error [500]"reason:
"Internal server error"stack: (...)get
stack: function () { [native code] }set stack:
function () { [native code] }__proto__: Middle
How do I get the error message that I threw from future?
Use it like that: return future.throw(new Meteor.Error(400, 'ololo'))
future.throw expects an Meteor.Error instance that in it's turn contains error message itself and additionally http response code. So 400 is Bad Request response code in that case and ololo is error message.
return isn't actually necessary here but I do it every time just to be sure I don't call any code after failure.

Node.js createClient Error: getaddrinfo OK at errnoException (dns.js:31:11)

Fixed now! The host wasn't found because I was including http in the url.
I'm experimenting with Node.js createClient, however it only works when I set the host to localhost. If I try e.g. http://google.com I get the error below. What is causing this problem, could it be a firewall issue?
var http = require('http');
var url = require('url');
var u = require('util');
var site = http.createClient(80, "http://google.com", false);
var req = site.request("GET", "/");
req.end();
req.on('response', function(res){
res.on('data', function(chunk){
console.log('BODY:' + chunk);
});
});
Error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: getaddrinfo OK
at errnoException (dns.js:31:11)
at Object.onanswer [as oncomplete] (dns.js:140:16)
Node.js process terminated
You're creating an HTTP request, and you should give it "google.com" as the host not "http://google.com"
Edit: It's not an url, that's why you don't put the protocol (http://) to it, it's the host.

Resources