Someone is eating my errors, how can I debug it? - javascript

I'm writing a react application using Router1. Here is how the final subscription looks like:
router
.renderResult()
.forEach(() => {
window.ga('send', 'pageview', window.location.pathname);
});
This stream throwing an error (unhandled error), but I don't see it in the console. If I put onError callback in forEach - I can log errors.
If I fix error in stream and create another stream inside, that throws an error, I don't see the message in console:
router
.renderResult()
.forEach(() => {
window.ga('send', 'pageview', window.location.pathname);
Observable.throw(1).subscribe();
});
And even if I replace Observable.throw(1).subscribe(); with simple throw 1 - result is the same, no messages in console and stream is broken.
But If I fix error in the stream, and create another stream that throws an error after some timeout, I see the message "rx.all.js:77 Uncaught 1" which is great.
router
.renderResult()
.forEach(() => {
window.ga('send', 'pageview', window.location.pathname);
setTimeout(() => Observable.throw(1).subscribe(), 1000);
});
So by default rx throws unhandled exceptions, but not in this case, why? Who eating my errors? Any ideas how can I debug it?

So I've found who was eating my tasty errors - superagent#2.0.0. Issue is already fixed and will be released in the next version.
Here is example how you can feed errors to superagent:
import { Observable } from 'rx';
import superagent from 'superagent';
const request = superagent.get('/');
Observable.defer(
Observable.fromNodeCallback(request.end, request, res => res.body)
).subscribe(() => {
throw new Error('tasty error');
});

Related

How to check for or avoid ERR_TIMED_OUT error?

I'm occasionally getting a ERR_TIMED_OUT when scraping a site and want to know how I can catch the error so I can start the loop processing it again?
This is the function I'm using the get the response:
const responsePending = page.waitForResponse((response) => {
return response.url().includes('cloudfront.net');
});
console.log('Wait for response...');
var response = await responsePending;
// when there's an error it doesn't print the next line
console.log('Response received: '+response.status());
And this is the error I'm sometimes getting:
This site can’t be XXXXX took too long to respond.
Try:
Checking the connection
Checking the proxy and the firewall
ERR_TIMED_OUT
Puppeteer also records this error in the logs:
crbug/1173575, non-JS module files deprecated.
https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagewaitforresponseurlorpredicate-options
Set the timeout option to 0
const responsePending = page.waitForResponse((response) => {
return response.url().includes('cloudfront.net');
},{timeout:0});

How to handle 404 error in a async/await?

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.

How to catch unhandledRejection?

I wrote a Telegram bot using TelegrafJS, this framework wraps the Telegram API. The problem that I'm facing is how to correctly manage the unhandled rejection, in fact when I call this method:
await ctx.deleteMessage(message_id);
where ctx is the instance of TelegrafJS I got:
Bot error: Error: 400: Bad Request: message to delete not found
this error happens 'cause the message_id that I passed no longer exists in Telegram chat. Now, the problem is that I have several controllers which can cause that problem.
I was looking at Promise.prototype.catch(), my question is: can I set up a global rejection handler for my application, or should I use a try/catch block to methods potentially subject to exceptions?
Yes you can, and it is pretty simple:
process.on('unhandledRejection', (err) => {
//handle it!
});
You can also catch the unhandled exceptions, using the same code basically:
process.on('uncaughtException', (err) => {
//handle it!
});
test this code:
bot.use((ctx, next) => {
try {
...
} catch(error) {
next();
}
})
For error handler, you can use:
bot.catch((err, ctx) => {
console.log(err);
return ctx.reply("Error Message");
});

How to handle backend errors from Node/Koa on frontend apollo-client

My frontend, using apollo-client, throws an exception when the backend returns an error after a request.
When the node server receives a request, I check the validity of the request's token using koa middleware. If the token is valid, the request is forwarded to the next middleware. If the token is invalid, I want to return a 401 access denied error to the client. To do this, I followed Koa's error documentation located here.
The code for the error handling middleware I wrote:
function userIdentifier() {
return async (ctx, next) => {
const token = ctx.request.headers.authorization
try {
const payload = checkToken(token)
ctx.user = {
id: payload.userId,
exp: payload.exp,
iat: payload.iat,
}
} catch (error) {
ctx.user = undefined
ctx.throw(401, "access_denied")
// throw new Error("access_denied")
}
await next()
}
}
This seemingly works on the backend, but not on the frontend. When the frontend receives this error, a JavaScript runtime error occurs. I am not sure what causes this.
Note, the unexpected "a" is the same "a" found in ctx.throw(401, "access_denied"). If it were instead ctx.throw(401, "x") the frontend shows "unexpected token x" instead.
The frontend code where the errors happens:
In an attempt to fix this, I followed Apollo's error handling documentation and used apollo-link-error.
const errorLink = onError(props => {
const { graphQLErrors, networkError } = props
console.log("ON ERROR", props)
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
)
if (networkError) console.log(`[Network error]: ${networkError}`)
})
Then I combine all links and create the Apollo client like this:
const link = ApolloLink.from([errorLink, authLink, httpLink])
export const client = new ApolloClient({
link,
cache: new InMemoryCache(),
})
The output of the debugging log in apollo-link-error is as follows:
Related Documents
Someone seems to be having an identical error, but a solution was not listed.
I found that the errors were handled correctly on the frontend when I began using this library on the backend: https://github.com/jeffijoe/koa-respond
Using just ctx.unauthenticated()
But I would still like to know more about how to return json/object-based errors with koa without a plugin helping

JavaScript errors not showing up in console?

fields is undefined in the following code snipped, but it is not logged to the console when the error happens. In this specific instance, why, and what is the de facto way to handle this?
"Testing" is logged to the console (Line #2), but the undefined variable fields (Line #4) is not being reported. The error is returned in an API response (Line #5) but with no relevant information such as line #, stack trace, etc.
How can I make errors like this log to the console, and why are they not?
export function post(req, res) {
console.log("Testing")
User.create( getFields(req, ["name_first", "name_last"]) )
.then(user => respondJSON (res, fields, { status: 201 }))
.catch(err => respondError (res, err))
}
Since the catch is responding with an error, I get the following API response:
{
"error": true,
"data": {
"message": "fields is not defined"
}
}
I am using Babel 6 and babel-node to run my code through NPM scripts. I am using morgan logging as well. Removing the middleware for logging does not alter the error output.
The automatic logging to console is a mechanism for unhandled exceptions. Because Promises automatically catch exceptions in the callbacks, the exceptions are no-longer unhandled, so nothing will be automatically logged.
If you want it to be logged, you could perhaps add a throw err at the end of your catch block. This will convert it into an unhandled promise rejection, which is typically handled similarly to an unhandled exception.
Because you didn't actually log the error?
export function post(req, res) {
console.log("Testing")
User.create( getFields(req, ["name_first", "name_last"]) )
.then(user => respondJSON (res, fields, { status: 201 }))
.catch(err => {
console.error(err);
respondError(res, err);
});
}
I had a similar problem caused by a 'finally' which was appended to the main async function running.
run()
.finally(()=>{process.exit(0)})
modifying it to:
run()
.catch(err => {console.log(err)})
.finally(()=>{process.exit(0)})
solved the problem

Categories