Replies: 103 comments 10 replies
-
For logging errors in the client side we have been doing the following: It basically sends errors to the server, that are in the end printed to |
Beta Was this translation helpful? Give feedback.
-
I'm also having this problem. I wonder: would simply returning a rejected promise from next's handleRequest (req, res, parsedUrl) {
// .....snip....
return this.run(req, res, parsedUrl)
.catch((err) => {
if (!this.quiet) console.error(err)
res.statusCode = 500
res.end(STATUS_CODES[500])
// rethrow error to create new, rejected promise
throw err;
})
} Then, in user code: const app = nextJs({ dev: process.env.NODE_ENV !== 'production' });
const nextJsHandler = app.getRequestHandler();
const expressApp = express();
app.prepare().then(() => {
// invoke express middlewares
// ...
// time to run next
expressApp.use(function(req, res, next) {
nextJsHandler(req, res).catch(e => {
// use rejected promise to forward error to next express middleware
next(e)
})
});
// Use standard express error middlewares to handle the error from next
// this makes it easy to log to sentry etc.
}) |
Beta Was this translation helpful? Give feedback.
-
@arunoda @rauchg Do you think the change I proposed immediately above would work? If so, happy to submit a PR |
Beta Was this translation helpful? Give feedback.
-
Agree to re-throw an error so we can play around with it. |
Beta Was this translation helpful? Give feedback.
-
I am also in the situation where we want to sent errors, both on server and client side, to a service similar to Sentry. I believe that the most valuable feature of such services/tools is to report issues that are most unexpected, which in my experience are uncaught errors in the wild (ie. client-side). Unfortunately, as previously stressed out in related issue #2334, Next.js’ client-side handlers keep these errors to themselves, with no possible way to pass them to Sentry of such other tool. What has bitten us particularly hard is this: a properly server-side rendered page is re-rendered as an error page if an uncaught exception occurs before React rendering on the client-side. This can be seen as either a great feature, but also a frustrating developer experience, as it essentially ruins the benefits of serving an already rendered document, on a surprisingly portion of clients. Here is a sample page that illustrates the problem: import React from 'react';
// Works well in Node 8, but crashes in Chrome<56, Firefox<48, Edge<15, Safari<10, any IE…
const whoops = 'Phew, I made it to the client-side…'.padEnd(80);
export default () => <pre>{whoops}</pre>; The above code can be perfectly server-side-rendered and delivered to the client, only to become a Flash Of Unwanted Content before the whole page is replaced on the client-side by the dreaded ”An unexpected error has occurred” message on most browsers, without any possible way to report the error to Sentry (or any other service/tool). This ”error swallowing” also prevents any leverage of the standard onerror handler, which most client-side error reporting tools hook onto (or the more modern, but not widespread, onunhandledrejection, which may be more suitable given the async nature of client-side code). Possible client-side solutionAs far as I can tell, this type of pre-React client-side error is swallowed in the Dear Next.js authors and maintainers, for the sake of control of what is rendered, what would you think would be acceptable/possible among the following ideas:
|
Beta Was this translation helpful? Give feedback.
-
This is something we've talked about internally. And we'll be addressing soon. |
Beta Was this translation helpful? Give feedback.
-
I'm using Sentry.io to report errors and the solution we apply is: 1- Configure raven-node on server side With this two steps we catch any unhandled exceptions both on client and server. 3- Create an The way to decide how to load if raven-node or ravenjs is solved importing dynamically depending if we are in client const webpack = require('webpack');
module.exports = {
// Do not show the X-Powered-By header in the responses
poweredByHeader: false,
webpack: (config) => {
config.plugins.push(new webpack.IgnorePlugin(/^raven$/));
return config;
},
}; |
Beta Was this translation helpful? Give feedback.
-
Can you show me how did you configured raven-js on your Do I need to send the all the errors manually at // _document constructor
constructor(props) {
super(props);
Raven
.config('...')
.install();
} |
Beta Was this translation helpful? Give feedback.
-
Next.js still outputs errors to With Sentry, you can enable Example implementation: const express = require('express');
const nextjs = require('next');
const Raven = require('raven');
const dev = process.env.NODE_ENV !== 'production';
// Must configure Raven before doing anything else with it
if (!dev) {
Raven.config('__DSN__', {
autoBreadcrumbs: true,
captureUnhandledRejections: true,
}).install();
}
const app = nextjs({ dev });
const handle = app.getRequestHandler();
const captureMessage = (req, res) => () => {
if (res.statusCode > 200) {
Raven.captureMessage(`Next.js Server Side Error: ${res.statusCode}`, {
req,
res,
});
}
};
app
.prepare()
.then(() => {
const server = express();
if (!dev) {
server.use((req, res, next) => {
res.on('close', captureMessage(req, res));
res.on('finish', captureMessage(req, res));
next();
});
}
[...]
server.get('/', (req, res) => {
return app.render(req, res, '/home', req.query)
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen('3000', (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
}); This is a very contrived example adapted from our actual code. I haven't tested it in this form. Let me know if it breaks. Of course, it would still be best if Next.js could pass those errors around to Express, so that we can use the Sentry/Express integration out of the box. |
Beta Was this translation helpful? Give feedback.
-
@tusgavomelo Sorry, for the late reply. We have update. In our app we have a helper file with a method responsible to get a Raven instance taking into account if we are on client or server side. let clientInstance;
let serverInstance;
const getRavenInstance = (key, config) => {
const clientSide = typeof window !== 'undefined';
if (clientSide) {
if (!clientInstance) {
const Raven = require('raven-js'); // eslint-disable-line global-require
Raven.config(key, config).install();
clientInstance = Raven;
}
return clientInstance;
}
if (!serverInstance) {
// NOTE: raven (for node) is not bundled by webpack (see rules in next.config.js).
const RavenNode = require('raven'); // eslint-disable-line global-require
RavenNode.config(key, config).install();
serverInstance = RavenNode;
}
return serverInstance;
}; This code runs both server side (when a request arrives) and client side. What we have done is configure webpack ( |
Beta Was this translation helpful? Give feedback.
-
@acanimal can you maybe provide a working example ? It seems I am not getting the full stack trace ? or maybe can you post your I am doing something like
|
Beta Was this translation helpful? Give feedback.
-
This seems like the place to ask for custom logger support since |
Beta Was this translation helpful? Give feedback.
-
The errors details are also available on the stderr stream. |
Beta Was this translation helpful? Give feedback.
-
Gotta love unortodox solutions
|
Beta Was this translation helpful? Give feedback.
-
Compact version of how to get correct Raven for node and browser w/o custom webpack config. Inspired by @acanimal comment // package.json
"browser": {
"raven": "raven-js"
}
// getRaven.js
const Raven = require('raven')
if (process.env.NODE_ENV === 'production') {
Raven.config('YOUR_SENTRY_DSN').install()
}
module.exports = Raven |
Beta Was this translation helpful? Give feedback.
-
@kelly-tock okay, I wrote up a quick note about how we use preloading with NextJS: https://jake.tl/notes/2021-04-04-nextjs-preload-hack |
Beta Was this translation helpful? Give feedback.
-
Hi, 2 things that I still don't understand regarding this issue:
|
Beta Was this translation helpful? Give feedback.
-
@justjake Thanks for the excellent writeup! While having to monkey-patch logging is a shame, I think using Sentry just released a new official Next.js SDK that has an interesting approach: it actually injects Sentry setup into the Webpack bundles for your app, both the client and server (https://github.com/getsentry/sentry-javascript/blob/master/packages/nextjs/src/utils/config.ts#L154-L155). Unfortunately, we're using Rollbar at my company, and Rollbar doesn't have any Next.js integration, so we'll have to do a manual setup. The In general, I think Next.js docs should incorporate discussion of error reporting. I had deferred adding error handling to the "last 10% work" of a new project launch and spent yesterday in a bit of a panic trying to figure out how on earth I was going to add it. I had just assumed it'd be as easy as adding Sentry/Rollbar/Bugsnag/etc usually is - just add it to the entry point - until I realized Next has no "entry point" without a custom server. If the use of |
Beta Was this translation helpful? Give feedback.
-
@thomasboyt Thanks for pointing out Sentry released something for Next.js! I'm gonna take a look at it very soon! For anyone interested: https://sentry.io/for/nextjs/ Also, we mentionned logging above, and we've released https://github.com/UnlyEd/simple-logger a few days ago, which is 1kB an universal. After trying out a lot of open source alternatives, we couldn't find something that felt just right. Maybe you'll find it as useful as we do! |
Beta Was this translation helpful? Give feedback.
-
thanks for writing that out but indeed we need a generic "error handler" for the server like pretty much any express.js production app will end up having so unexpected errors can be caught, a user-friendly 500 can be return and the error can be sent to any error reporting library. fingers crossed this will be sorted out soon as it's rather important. |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
I tried with this preloading script. It printed error messages but missed request URL and stack trace. It is super hard or impossible to know where the error was happening. Edit: I have ended up using https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs |
Beta Was this translation helpful? Give feedback.
-
Worked for me! |
Beta Was this translation helpful? Give feedback.
-
We need a server side ErrorBoundary 🤗 |
Beta Was this translation helpful? Give feedback.
-
Hi all, any update here for example like official suggested solution ? My 5 cents here are that a proper solution would be to eject and use custom server.ts/js then wrap with another express middleware that for every catch block logs the exception to our preferred logging system. This works good for us but breaks the developer experience as having custom server in typescript like in this example https://github.com/vercel/next.js/tree/canary/examples/custom-server-typescript because cannot debug then. Nodemon ts-node node inspector with custsom next server is not working. So my proposal is this (I think already exist need to try it) |
Beta Was this translation helpful? Give feedback.
-
I've found next-logger is able to capture all api errors and turn them into a standard pino log stream It does this by intercepting all console.* calls. When there is an exception calling an api route (error is explicitly thrown) next.js will basically call I'm curious what exactly the sentry SDK does! |
Beta Was this translation helpful? Give feedback.
-
After a lot of research I found the best solution to report server side rendering errors is to use custom _error.jsx and do the report inside Error component getInitialProps like below [_error.tsx] |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
It is strange to see no ready to use solutions available in NextJs to catch and log server side errors in production.. |
Beta Was this translation helpful? Give feedback.
-
Wondering if OpenTelemetry can be used to extract all errors: https://nextjs.org/docs/app/building-your-application/optimizing/open-telemetry I just read through the docs and don't know yet if this data is available. Probably someone knows more. I am only interested in collecting errors and storing them in our database. |
Beta Was this translation helpful? Give feedback.
-
Hi,
I'm in the situation where we want to sent errors, both on server and client side, to Sentry tool.
Our app uses Express as a custom server. Basically we create an express app, apply some middlewares but delegate all the real job to the next.js handle:
With this approach next.js takes control over the rendering process and any error is catch by next.js and the only way I have to process it is overriding the
_error.js
page file.Within that
_error.js
file I need a universal way to report errors to Sentry. Currently there are two libraries (raven
for node andraven-js
por javascript). The proble is I can't import both of them becauseraven
works for SSR but fails when webpack builds the bundle, and alsoraven-js
fails due XMLHTTPRequest dependency too.Is there a way I can be notified for next.js error on server side?
Beta Was this translation helpful? Give feedback.
All reactions