рдирдорд╕реНрддреЗ,
рдореИрдВ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реВрдВ рдЬрд╣рд╛рдВ рд╣рдо рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рддрд░рдл рд╕реЗ рд╕рдВрддрд░реА рдЯреВрд▓ рдкрд░ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рд╣рдорд╛рд░рд╛ рдРрдк рдПрдХ рдХрд╕реНрдЯрдо рд╕рд░реНрд╡рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореВрд▓ рд░реВрдк рд╕реЗ рд╣рдо рдПрдХ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдРрдк рдмрдирд╛рддреЗ рд╣реИрдВ, рдХреБрдЫ рдорд┐рдбрд▓рд╡реЗрдпрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рд╕рднреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдп рдЕрдЧрд▓реЗ.рдЬреЗрдПрд╕ рд╣реИрдВрдбрд▓ рдХреЛ рд╕реМрдВрдкрддреЗ рд╣реИрдВ:
const app = nextJs({ dev: process.env.NODE_ENV !== 'production' });
const handler = routes.getRequestHandler(app);
const expressApp = express();
...
...
expressApp.use(morgan('combined', { stream: logger.stream }));
expressApp.use(statsdMiddleware);
// Add security
expressApp.use(helmet());
// Sentry handler
expressApp.use(sentry.requestHandler());
// Load locale and translation messages
expressApp.use(i18n);
// Next.js handler
expressApp.use(handler);
// Sentry error handler.
// MUST be placed before any other express error handler !!!
expressApp.use(sentry.errorHandler());
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде next.js рдкреНрд░рддрд┐рдкрд╛рджрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЛ next.js рджреНрд╡рд╛рд░рд╛ рдкрдХрдбрд╝ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ _error.js
рдкреГрд╖реНрда рдлрд╝рд╛рдЗрд▓ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реИред
рдЙрд╕ _error.js
рдлрд╝рд╛рдЗрд▓ рдХреЗ рднреАрддрд░ рдореБрдЭреЗ рд╕рдВрддрд░реА рдХреЛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рддрд░реАрдХрд╛ рдЪрд╛рд╣рд┐рдПред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рджреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИрдВ ( raven
рдиреЛрдб рдХреЗ рд▓рд┐рдП рдФрд░ raven-js
рдкреЛрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ)ред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рдЙрди рджреЛрдиреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рдХреНрдпреЛрдВрдХрд┐ raven
SSR рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рд╡реЗрдмрдкреИрдХ рдмрдВрдбрд▓ рдмрдирд╛рддрд╛ рд╣реИ рддреЛ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╕рд╛рде рд╣реА raven-js
XMLHTTPRequest рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдХрд╛рд░рдг рднреА рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдХреНрдпрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдореБрдЭреЗ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдЕрдЧрд▓реА.рдЬреЗрдПрд╕ рддреНрд░реБрдЯрд┐ рдХреЗ рд▓рд┐рдП рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?
рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдореЗрдВ рд▓реЙрдЧрд┐рдВрдЧ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
https://gist.github.com/jgautheron/044b88307d934d486f59ae87c5a5a5a0
рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд░реНрд╡рд░ рдХреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рднреЗрдЬрддрд╛ рд╣реИ, рдЬреЛ рдЕрдВрдд рдореЗрдВ stdout
рдореБрджреНрд░рд┐рдд рд╣реЛрддреА рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ Docker
рд▓реЙрдЧрд┐рдВрдЧ рдбреНрд░рд╛рдЗрд╡рд░ рджреНрд╡рд╛рд░рд╛ рдкрдХрдбрд╝реА рдЬрд╛рддреА рд╣реИрдВред
рд╣рдордиреЗ react-guard
рд╕рд╛рде SSR рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрдХрдбрд╝рд╛ рд╣реИ рдФрд░ рдХреЛрд░ рдиреЗрдХреНрд╕реНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдореБрдЭреЗ рднреА рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рд╣реИред рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ: рдХреНрдпрд╛ рдЕрдЧрд▓реЗ рдХреЗ handleRequest
рд╕реЗ рдЕрд╕реНрд╡реАрдХреГрдд рд╡рд╛рджреЗ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛? рдпрд╣реА рд╣реИ, рдпрд╣рд╛рдВ рдХреЛрдб рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП:
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;
})
}
рдлрд┐рд░, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрдб рдореЗрдВ:
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.
})
@arunoda @rauchg рдХреНрдпрд╛ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЬреЛ рдмрджрд▓рд╛рд╡ рддреБрд░рдВрдд рдКрдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛? рдЕрдЧрд░ рдРрд╕рд╛ рд╣реИ, рддреЛ рдкреАрдЖрд░ рд╕рдмрдорд┐рдЯ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреА
рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдлреЗрдВрдХрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣рдордд рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рд╕рдХреЗрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ renderToHTML
рднреА рдлрд┐рд░ рд╕реЗ рдлреЗрдВрдХрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ ...
рдореИрдВ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рднреА рд╣реВрдВ рдЬрд╣рд╛рдВ рд╣рдо рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рддрд░рдл рд╕реЗ рд╕рдВрддрд░реА рдЬреИрд╕реА рд╕реЗрд╡рд╛ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдРрд╕реА рд╕реЗрд╡рд╛рдУрдВ/рдЙрдкрдХрд░рдгреЛрдВ рдХреА рд╕рдмрд╕реЗ рдореВрд▓реНрдпрд╡рд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рдЙрди рдореБрджреНрджреЛрдВ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рд╣реИ рдЬреЛ рд╕рдмрд╕реЗ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╣реИрдВ, рдЬреЛ рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдореЗрдВ рдЬрдВрдЧрд▓реА (рдпрд╛рдиреА рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб) рдореЗрдВ рдЕрдирдЬрд╛рди рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдВрдХ #2334 рдореЗрдВ рдЬреЛрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, Next.js рдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рд╣реИрдВрдбрд▓рд░ рдЗрди рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдкрдиреЗ рдкрд╛рд╕ рд░рдЦрддреЗ рд╣реИрдВ, рдРрд╕реЗ рдЕрдиреНрдп рдЯреВрд▓ рдХреЗ рд╕рдВрддрд░реА рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред
рдЬрд┐рд╕ рдЪреАрдЬ рдиреЗ рд╣рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХрдард┐рди рдХрд╛рдЯ рджрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдпрд╣ рд╣реИ: рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдкрд░ рд░рд┐рдПрдХреНрдЯ рд░реЗрдВрдбрд░рд┐рдВрдЧ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рди рдЖрдпрд╛ рд╣реБрдЖ рдЕрдкрд╡рд╛рдж рд╣реЛрдиреЗ рдкрд░ рдПрдХ рдареАрдХ рд╕реЗ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд░реЗрдВрдбрд░ рдХрд┐рдП рдЧрдП рдкреЗрдЬ рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдкреЗрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдЗрд╕реЗ рдпрд╛ рддреЛ рдПрдХ рдорд╣рд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рдбреЗрд╡рд▓рдкрд░ рдЕрдиреБрднрд╡ рднреА, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╣рд┐рд╕реНрд╕реЗ рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд╛рднреЛрдВ рдХреЛ рдмрд░реНрдмрд╛рдж рдХрд░ рджреЗрддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рдПрдХ рдирдореВрдирд╛ рдкреГрд╖реНрда рд╣реИ рдЬреЛ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ:
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>;
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб-рд░реЗрдВрдбрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдЕрд╡рд╛рдВрдЫрд┐рдд рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдлреНрд▓реИрд╢ рдмрдирдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдкреВрд░реЗ рдкреГрд╖реНрда рдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдкрд░ рдЦрддрд░рдирд╛рдХ "рдПрдХ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рддреНрд░реБрдЯрд┐ рд╣реБрдИ рд╣реИ" рд╕рдВрджреЗрд╢ рдЕрдзрд┐рдХрд╛рдВрд╢ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдкрд░ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдП , рд╕рдВрддрд░реА (рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реЗрд╡рд╛/рдЙрдкрдХрд░рдг)
рдпрд╣ "рддреНрд░реБрдЯрд┐ рдирд┐рдЧрд▓рдиреЗ" рдорд╛рдирдХ рдСрдирд░рд░ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХрд┐рд╕реА рднреА рдЙрддреНрддреЛрд▓рди рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдЯреВрд▓ рд╣реБрдХ (рдпрд╛ рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ, рд▓реЗрдХрд┐рди рд╡реНрдпрд╛рдкрдХ рдирд╣реАрдВ, рдЧреИрд░-рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ , рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдХреА
рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реВрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░реА-рд░рд┐рдПрдХреНрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐ Next.js рдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯ/index.js рдореЗрдВ try
/ catch
рдмреНрд▓реЙрдХ рдореЗрдВ рдирд┐рдЧрд▓ рд▓реА рдЬрд╛рддреА рд╣реИ рдЬрд╣рд╛рдВ Component
рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ ErrorComponent
(рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд▓рд╛рдЗрди 67-72 ) рдХреЗ рдореВрд▓реНрдп рдкрд░ рдлрд┐рд░ рд╕реЗ рдЕрд╕рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдкреНрд░рд┐рдп Next.js рд▓реЗрдЦрдХ рдФрд░ рдЕрдиреБрд░рдХреНрд╖рдХ, рдЬреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдХреНрдпрд╛ рд╕реНрд╡реАрдХрд╛рд░реНрдп/рд╕рдВрднрд╡ рд╣реЛрдЧрд╛:
catch
рдмреНрд▓реЙрдХ рдореЗрдВ рдПрдХ рд╣реБрдХ рдкреЗрд╢ рдХрд░реЗрдВ?рдЗрд╕ рддрд░рд╣ рдХреА рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рдЗрдВрдЯ/рдЗрдВрдбреЗрдХреНрд╕.рдЬреЗрдПрд╕ рдореЗрдВ рдЙрд╕ рдХреИрдЪ рдмреНрд▓реЙрдХ рдореЗрдВ рдПрдХ рд╣реБрдХ рдкреЗрд╢ рдХрд░реЗрдВ?
рддреНрд░реБрдЯрд┐ рдХреЛ рдПрдХ рдЖрддрдВрдХ/рдСрдирд╣реИрдВрдбрд▓ рд░рд┐рдЬреЗрдХреНрд╢рди рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХрд░реЗрдВ, рдпрджрд┐ рдХреЛрдИ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ?
рдпрд╣ рдРрд╕реА рдЪреАрдЬ рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдордиреЗ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдмрд╛рдд рдХреА рд╣реИред рдФрд░ рд╣рдо рдЬрд▓реНрдж рд╣реА рд╕рдВрдмреЛрдзрд┐рдд рдХрд░реЗрдВрдЧреЗред
рдореИрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Sentry.io рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЬреЛ рд╕рдорд╛рдзрд╛рди рд╣рдо рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рд╣реИ:
1- рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд░реЗрд╡реЗрди-рдиреЛрдб рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
2- рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд░реИрд╡реЗрдВрдЬ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ (рд╣рдордиреЗ рдЗрд╕реЗ _document
рдкрд░ рдмрдирд╛рдпрд╛ рд╣реИред
рдЗрди рджреЛ рдЪрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рджреЛрдиреЛрдВ рдкрд░ рдХрд┐рд╕реА рднреА рдЕрдирдЪрд╛рд╣реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВред
3- рдПрдХ _error
рдкреЗрдЬ рдмрдирд╛рдПрдВред рдиреЗрдХреНрд╕реНрдЯрдЬ рдПрдХ рдмрд╛рд░ рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреЛрдИ рднреА рддреНрд░реБрдЯрд┐ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрднрд╛рд▓рддреА рд╣реИ (рдЪрд╛рд╣реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдпрд╛ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдХреЛрдИ рднреА рд╣реЛ) рдЙрд╕ рдкреГрд╖реНрда рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред _error рдкреГрд╖реНрда рдХреА getInitialProps
рдкрджреНрдзрддрд┐ рдореЗрдВ рд╣рдо рд╕рдВрддрд░реА рдХреЛ рддреНрд░реБрдЯрд┐ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдЧрд░ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ const Raven = require('raven-js');
рдпрд╛ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб const Raven = require('raven');
рдореЗрдВ рд╣реИрдВ рддреЛ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рд░реЗрд╡реЗрди-рдиреЛрдб рдпрд╛ рд░реЗрд╡реЗрдирдЬ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЖрдпрд╛рдд рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред
рдиреЛрдЯ рд╣рдо webpack рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рд╣реИ рдмрдВрдбрд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП raven
рдореЙрдбреНрдпреВрд▓ (рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рд╕реЗ рдПрдХ) рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ next.config.js
рдХреЗ рд╕рд╛рде:
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;
},
};
@ acanimal
2- рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд░реИрд╡реЗрдВрдЬ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ (рд╣рдордиреЗ рдЗрд╕реЗ _document.
рдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдиреЗ рдЕрдкрдиреЗ _document.js
рдкрд░ рд░реЗрд╡реЗрди-рдЬреЗрдПрд╕ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛? рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬрдм рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ рддреЛ рд╕рдВрддрд░реА рдкрд░ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рдХреНрдпрд╛ рдореБрдЭреЗ рд╕рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ _error.js
рдкреГрд╖реНрда рдкрд░ рд╕рдВрддрд░реА рдХреЛ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?
// _document constructor
constructor(props) {
super(props);
Raven
.config('...')
.install();
}
Next.js рдЕрднреА рднреА рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ console.error
рдкрд░ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЖрдк рдЗрд╕реЗ рд╢рд╛рдВрдд рдкрд░ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
рд╕рдВрддрд░реА рдХреЗ рд╕рд╛рде, рдЖрдк рдЗрд╕ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ autoBreadcrumbs
рдХреЛ рд╕рдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдВрджреЗрд╢ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреИрдкреНрдЪрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╢реАрд░реНрд╖рдХ рдХрдо рд╡рд░реНрдгрдирд╛рддреНрдордХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдЕрднреА рднреА рдкреВрд░реНрдг рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рд╣реЛрдЧрд╛ред
рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
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);
});
рдпрд╣ рд╣рдорд╛рд░реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдПрдХ рдмрд╣реБрдд рд╣реА рдХрд╛рд▓реНрдкрдирд┐рдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдореИрдВрдиреЗ рдЗрд╕ рд░реВрдк рдореЗрдВ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдЯреВрдЯ рдЬрд╛рдП рддреЛ рдмрддрд╛ рджреЗрдирд╛ред
рдмреЗрд╢рдХ, рдпрд╣ рдЕрднреА рднреА рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ Next.js рдЙрди рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдХреЗ рдЖрд╕рдкрд╛рд╕ рднреЗрдЬ рд╕рдХреЗ, рддрд╛рдХрд┐ рд╣рдо рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд╕рдВрддрд░реА/рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдПрдХреАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВред
@tusgavomelo рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рджреЗрд░ рд╕реЗ рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдПред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрдбреЗрдЯ рд╣реИред рд╣рдорд╛рд░реЗ рдРрдк рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд░реЗрд╡реЗрди рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рд╛рдЗрд▓ рд╣реИ рдпрджрд┐ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдпрд╛ рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл рд╣реИрдВред
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;
};
рдпрд╣ рдХреЛрдб рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб (рдЬрдм рдХреЛрдИ рдЕрдиреБрд░реЛрдз рдЖрддрд╛ рд╣реИ) рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рджреЛрдиреЛрдВ рдЪрд▓рд╛рддрд╛ рд╣реИред рд╣рдордиреЗ рдЬреЛ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ raven
рдкреИрдХреЗрдЬ рдХреЛ рдмрдВрдбрд▓ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╡реЗрдмрдкреИрдХ ( next.config.js
рдлрд╝рд╛рдЗрд▓) рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реИред
@acanimal рдХреНрдпрд╛ рдЖрдк рд╢рд╛рдпрдж рдПрдХ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдкреВрд░рд╛ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ? рдпрд╛ рд╢рд╛рдпрдж рдЖрдк рдЕрдкрдирд╛ _error.js
рдкреЛрд╕реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдореИрдВ рдЕрдкрдиреЗ _error.js
RavenInstance.captureException(err)
рдЬреИрд╕рд╛ рдХреБрдЫ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЛ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реБрдИрдВ рдФрд░ рд╕рд╛рде рд╣реА рдХрд╣рд╛рдВ?
export default class Error extends React.Component {
static getInitialProps({ res, err }) {
const RavenInstance = getRavenInstance('__SENTRY__')
if (!(err instanceof Error)) {
err = new Error(err && err.message)
}
RavenInstance.captureException(err)
// const statusCode = res ? res.statusCode : err ? err.statusCode : null;
return { }
}
render() {
return (
<div>
<p>An error occurred on server</p>
</div>
)
}
}
рдЗрд╕ рдХреЗ рдмрд╛рдж рд╕реЗ рдХрд╕реНрдЯрдо рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдкреВрдЫрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдЧрд╣ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ quiet
рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП false
рдХреЗ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдФрд░ рдЗрд╕ рддрд░рд╣ рджреЗрдЦрдиреЗ рд╕реЗ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╢реБрджреНрдзрд┐рдХрд░рдг, рдЕрднреА рддрдХ рдХреЗрд╡рд▓ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реИрдХ рдпрд╣рд╛рдБ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдореЙрдбреНрдпреВрд▓ рдкрд░ рдЕрдЧрд▓реЗ рд╕рдорд╛рд╢реЛрдзрди рд╕реНрдХреНрд░реАрди рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП quiet
рдХреЛ рдЧрд▓рдд рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛ред
рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг stderr рд╕реНрдЯреНрд░реАрдо рдкрд░ рднреА рдЙрдкрд▓рдмреНрдз рд╣реИред
process.stderr.write = error => yourErrorLog(error);
_рдЕрдиреЛрд░реНрдЯреЛрдбреЙрдХреНрд╕_рд╕рдорд╛рдзрд╛рдиреЛрдВ рд╕реЗ рдкреНрдпрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
function installErrorHandler(app) {
const _renderErrorToHTML = app.renderErrorToHTML.bind(app)
const errorHandler = rollbar.errorHandler()
app.renderErrorToHTML = (err, req, res, pathname, query) => {
if (err) {
errorHandler(err, req, res, () => {})
}
return _renderErrorToHTML(err, req, res, pathname, query)
}
return app
}
// ┬п\_(уГД)_/┬п
рдХрд╕реНрдЯрдо рд╡реЗрдмрдкреИрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди w/o рдиреЛрдб рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд░реЗрд╡реЗрди рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдХрд╛ рдХреЙрдореНрдкреИрдХреНрдЯ рд╕рдВрд╕реНрдХрд░рдгред @acanimal рдХрдореЗрдВрдЯ рд╕реЗ рдкреНрд░реЗрд░рд┐рдд
// 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
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд╡рд░рд┐рдд рдкреБрдирд░реНрдХрдердиред
// pages/_error.js
import Raven from 'raven';
...
static async getInitialProps({ store, err, isServer }) {
if (isServer && err) {
// https://github.com/zeit/next.js/issues/1852
// eslint-disable-next-line global-require
const Raven = require('raven');
Raven.captureException(err);
}
...
// next.config.js
config.plugins.push(new webpack.IgnorePlugin(/^raven$/));
@acanimal рдХреА рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
raven
(рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕реБрдЭрд╛рдП рдЧрдП рд╡реЗрдмрдкреИрдХ рдХреЗ рд╕рд╛рде рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ) рдФрд░ raven-js
рджреЛрдиреЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рдлрд┐рд░ рдЖрдЗрд╕реЛрдореЛрд░реНрдлрд┐рдХ рд░реЗрд╡реЗрди рдХреЛ рддрддреНрдХрд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╣рд╛рдпрдХ рдмрдирд╛рдПрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП lib/raven.js
import Raven from 'raven-js';
// https://gist.github.com/impressiver/5092952
const clientIgnores = {
ignoreErrors: [
'top.GLOBALS',
'originalCreateNotification',
'canvas.contentDocument',
'MyApp_RemoveAllHighlights',
'http://tt.epicplay.com',
"Can't find variable: ZiteReader",
'jigsaw is not defined',
'ComboSearch is not defined',
'http://loading.retry.widdit.com/',
'atomicFindClose',
'fb_xd_fragment',
'bmi_SafeAddOnload',
'EBCallBackMessageReceived',
'conduitPage',
'Script error.',
],
ignoreUrls: [
// Facebook flakiness
/graph\.facebook\.com/i,
// Facebook blocked
/connect\.facebook\.net\/en_US\/all\.js/i,
// Woopra flakiness
/eatdifferent\.com\.woopra-ns\.com/i,
/static\.woopra\.com\/js\/woopra\.js/i,
// Chrome extensions
/extensions\//i,
/^chrome:\/\//i,
// Other plugins
/127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
/webappstoolbarba\.texthelp\.com\//i,
/metrics\.itunes\.apple\.com\.edgesuite\.net\//i,
],
};
const options = {
autoBreadcrumbs: true,
captureUnhandledRejections: true,
};
let IsomorphicRaven = null;
if (process.browser === true) {
IsomorphicRaven = Raven;
IsomorphicRaven.config(SENTRY_PUBLIC_DSN, {
...clientIgnores,
...options,
}).install();
} else {
// https://arunoda.me/blog/ssr-and-server-only-modules
IsomorphicRaven = eval("require('raven')");
IsomorphicRaven.config(
SENTRY_DSN,
options,
).install();
}
export default IsomorphicRaven;
рдлрд┐рд░ рдЖрдк рдЗрд╕реЗ рдЕрдкрдиреЗ pages/_error.js
рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рддрд░рдл рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
import NextError from 'next/error';
import IsomorphicRaven from 'lib/raven';
class MyError extends NextError {
static getInitialProps = async (context) => {
if (context.err) {
IsomorphicRaven.captureException(context.err);
}
const errorInitialProps = await NextError.getInitialProps(context);
return errorInitialProps;
};
}
export default MyError;
рдпрд╣рд╛рдВ рд░реЛрд▓рдмрд╛рд░ рд╕реЛрд░реНрд╕рдореИрдк рд╡реЗрдкрдмреИрдХ рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдореЗрд░рд╛ рдкреАрдЖрд░ рд╣реИ https://github.com/thredup/rollbar-sourcemap-webpack-plugin/pull/56 Next.js рд╕рдкреЛрд░реНрдЯ рдХреЗ рд╕рд╛рде :)
@tusgavomelo , рдХреНрдпрд╛ рдЖрдк рд╕реНрдЯреНрд░реАрдо рдкрд░ рдореМрдЬреВрдж рддреНрд░реБрдЯрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВ?
"process.stderr.write = error => yourErrorLog (рддреНрд░реБрдЯрд┐);"
рдиреЛрдб рдХрдВрд╕реЛрд▓ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреЛрдб рдХреА рдпрд╣ рдкрдВрдХреНрддрд┐ рдХрд╣рд╛рдВ рд▓рд┐рдЦрдиреА рдЪрд╛рд╣рд┐рдП?
рд╡рд╣ рдХреЗрд╡рд▓ рдЧреНрд░рд╛рд╣рдХ рдкрдХреНрд╖ рд╣реИред
Rollbar.error('some error')
@ рдЯреАрдХреА 99 рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ @sentry/browser
рд▓рд┐рдП рд╕рдорд╛рди рд╕рдорд╛рдзрд╛рди рд╣реИ? рд╢рд╛рдпрдж рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдЕрджреНрдпрддрди рдХрд░реЗрдВ?
@sheerun рдореИрдВ рдЕрдм рддрдХ raven
рдФрд░ raven-js
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рд╡реЗ рд╢рд╛рдпрдж рдкрджрд╛рд╡рдирдд рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рд╕рднреА рдирдИ рд╕реБрд╡рд┐рдзрд╛рдПрдВ рдЕрдм @sentry/node
рдФрд░ @sentry/browser
рдЬреЛрдбрд╝ рджреА рдЧрдИ рд╣реИрдВред рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рдЗрди рдирдП рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рджреЗрдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдЕрдЧрд░ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдг рд╣реИ рддреЛ рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдКрдВрдЧрд╛ред
рд╡рд┐рде-рд╕реЗрдВрдЯреНрд░реА рдЙрджрд╛рд╣рд░рдг рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
@timneutkens рдореИрдВ рджреЗрдЦрддрд╛ рд╣реВрдВ рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрддрд░реА рдХреЛ рдРрдк рдХреЗ рдЕрдВрджрд░ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕рд░реНрд╡рд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдореЗрдВ рдмрд╣реБрдд рджреЗрд░ рд╣реЛ рдЪреБрдХреА рд╣реИред рдЙрдЪрд┐рдд рд╕рдорд╛рдзрд╛рди рд╢рд╛рдпрдж рдХрд╣реАрдВ @sentry/node
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛
@sheerun рдореИрдВ рдЙрд╕реА рдореБрджреНрджреЗ рдХреЛ рдорд╛рд░ рд░рд╣рд╛ рд╣реВрдВред @sentry/node
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рддреБрдЪреНрдЫ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд░реАрдбрдореА рдПрдХ рдХрд╕реНрдЯрдо рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдореИрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рд╣рдорд╛рд░реЗ рдХрд╕реНрдЯрдо Express.js рд╕рд░реНрд╡рд░ рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕рдВрддрд░реА рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдорд┐рдбрд▓рд╡реЗрдпрд░ рддреНрд░реБрдЯрд┐ рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдиреЗрдХреНрд╕реНрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдареАрдХ рдмрд╛рдж рд╕рдВрддрд░реА рдХреЗ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрд╕ рдмрд┐рдВрджреБ рд╕реЗ рддреНрд░реБрдЯрд┐ рдкрд╣рд▓реЗ рд╣реА рдирд┐рдЧрд▓ рд▓реА рдЧрдИ рд╣реИ рдФрд░ рд╕рдВрддрд░реА рдЗрд╕реЗ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рд╣реИред
рдореИрдВ @sentry/browser
рдХрд╛ рдЙрдкрдпреЛрдЧ getInitialProps
рдХреЗ _error.js
рдореЗрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рджреЛрдиреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ @sentry/browser
рдореЗрдВ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд╕рдкреЛрд░реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд╕реЗрдВрдЯреНрд░реА рдореЗрдВ рдЗрд╡реЗрдВрдЯ рдорд┐рд▓ рд░рд╣реЗ рд╣реИрдВред
рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ рдХрд╕реНрдЯрдо рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╕рд░реНрд╡рд░ рдХреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ Sentry.init()
рдорд╛рдзреНрдпрдо рд╕реЗ @sentry/node
Sentry.init()
рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рдХреЙрд▓ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рд╢рд╛рдпрдж рдпрд╣ рдХреБрдЫ рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рд╕реЗрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдПрд╕рдПрд╕рдЖрд░ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред
рдпрд╣рд╛рдБ рдЙрд╕ рд╕реЗрдЯрдЕрдк рдХрд╛ рд╕рд╛рд░ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореИрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ: https://gist.github.com/mcdougal/7bf001417c3dc4b579da224b12776691
рджрд┐рд▓рдЪрд╕реНрдк!
рдпрд╣рд╛рдБ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдЪрд▓ рд░рд╣реА рд╣реИ (рдЬреЛ рдереЛрдбрд╝рд╛ рдбрд░рд╛рд╡рдирд╛ рд╣реИ, рдФрд░ рд╢рд╛рдпрдж рднрдВрдЧреБрд░ рдФрд░ рдЕрд╡рд╛рдВрдЫрдиреАрдп рд╣реИ)ред _error.js
рдореЗрдВ рдЕрдкрдиреЗ рдкрд░рд┐рд╡рд░реНрддрди рд▓рд╛рдЧреВ рдХрд░рдирд╛:
ReferenceError: XMLHttpRequest is not defined
рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИError: Sentry syntheticException
рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИрдпрд╣ рд╕рдордЭрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рдорд╛рдзрд╛рди рдХреНрдпрд╛ рд╣реИред рдиреЗрдХреНрд╕реНрдЯ рдХреЗ рдбреЙрдХреНрд╕ рдЕрдм рдПрдХ рдХрд╕реНрдЯрдо <App>
рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣реА "рд╕реЗрдВрдЯреНрд░реА рдХреЗ рд╕рд╛рде" рдЙрджрд╛рд╣рд░рдг рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдкрд╣рд▓реА рдмрд╛рд░ рдРрдк рд░реЗрдВрдбрд░ рд╣реЛрдиреЗ рддрдХ рддреНрд░реБрдЯрд┐ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд╣реАрдВ рд╣реЛрдЧреАред рдЕрдЧрд▓рд╛ рд░рд╛рд╕реНрддрд╛ рдкрд╣рд▓реЗ рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдкреЗрдЬ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╕рдордпред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрдпреЛрдЧ рд╕реЗ рдпрд╣ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реЛ рдЬрдм рдРрдк рдкрд╣рд▓реА рдмрд╛рд░ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛ, рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИред
рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдореЗрд░реЗ рд▓рд┐рдП @timneutkens рдХреЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЪрд▓рд╛рдирд╛ рдФрд░ рдореЗрд░реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреАрдПрд╕рдПрди рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ 400 рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╕рдВрддрд░реА (рдПрдкреАрдЖрдИ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг 7) рдХреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИред
{"error":"Bad data reconstructing object (JSONDecodeError, Expecting value: line 1 column 1 (char 0))"}
@mcdougal рдореЗрд░реЗ рдХрд╛рдо рдирд╣реАрдВ рдЖрдпрд╛ред рд╡реИрд╢реНрд╡рд┐рдХ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд╕реЗрдЯрдЕрдк рд╣реЛрдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рдерд╛ рдЬреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рддрдХ рдмреБрд▓рдмреБрд▓реЗ рд╣реЛ, рд▓реЗрдХрд┐рди рдЙрд╕ рд╣реИрдХ рдХреЗ рд╕рд╛рде рднреА рдореБрдЭреЗ 301 рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рдорд┐рд▓реЗрдВрдЧреАред
рдореИрдВ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рдореЗрд░реЗ рд╕рдВрддрд░реА рд╕реНрд╡рдпрдВ-рд╣реЛрд╕реНрдЯ рдХрд┐рдП рдЧрдП рд╕реЗрдЯрдЕрдк рдореЗрдВ рдЧрд▓рдд рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреИрд╕реЗ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдИ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИрдВ рдФрд░ рдпрд╣ рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИред
рдореИрдВ @sentry/browser
рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрд╕реА рддрд░рд╣ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреИрд╕реЗ рдХрд┐ рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЗрд╕рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рд╕реЗ рдореЗрд░реА рд╕рдВрддрд░реА рдХреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рднреЗрдЬ рд░рд╣рд╛ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдирд╣реАрдВ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рдорд╛рди рдХреЛрдб рд╣реИред
@ рдЬреМрдиреА рдХреНрдпрд╛ рдЖрдк рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕рд░реНрд╡рд░ рд╕реЗ рднреЗрдЬ рд░рд╣рд╛ рд╣реИ? рдЖрдкрдиреЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛? рдЙрджрд╛рд╣рд░рдг рдХрд╛ рд░реАрдбрдореА рдпрд╣ рднреА рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
@timrogers рд╣рд╛рдБ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрд░рд╛ рдмреБрд░рд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рд╕реЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рддреНрд░реБрдЯрд┐ рдЖ рд░рд╣реА рдереА рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдЯреНрд░рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ :(
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрддрд░реА рдХреЗ рд╕рд╛рде рд╡рд░реНрддрдорд╛рди рдЙрджрд╛рд╣рд░рдг getInitialProps рдореЗрдВ рдлреЗрдВрдХрдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдирд╣реАрдВ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдкреЗрдбрд╝ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВ .. рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рддреНрд░реБрдЯрд┐рдпрд╛рдВ getInitialProps рд╕реЗ рд╣реИрдВред
@sheerun рдХреНрдпрд╛ рдЖрдк рдКрдкрд░ рджрд┐рдП рдЧрдП рдореИрдХрдбреЙрдЧрд▓ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЛ рдЖрдЬрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ? рдпрд╣ рд╕рд╣реА рдирд╣реАрдВ рд╣реИ (рдЕрдЬреАрдм рд╕рд┐рдВрдереЗрдЯрд┐рдХ рд╕рдВрддрд░реА рддреНрд░реБрдЯрд┐рдпрд╛рдВ) рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рд╕рднреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВ рдФрд░ рдореИрдВ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдЕрдЧрд░ рдпрд╣ рд╕рдЪ рд╣реИ, рддреЛ рд╕рдВрднрд╡рддрдГ рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ Next.js рдЗрд╕реЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛ (рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЗрд╕реЗ рд╕рд░реНрд╡рд░.рдЬреЗрдПрд╕ рд╕рдВрддрд░реА рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИ?)
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдереЛрдбрд╝реЗ рджреЛ рдкреНрд░рдореБрдЦ рдореБрджреНрджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
рдЕрд╕рд▓ рдореЗрдВ рдЖрдЧреЗ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рдж рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдХрд╕реНрдЯрдо рддреНрд░реБрдЯрд┐ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХрдкреНрд░реЙрдкреНрд╕ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдлрд╛рдпрд░рд┐рдВрдЧ рднреА рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрдм рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо _app рдХреЗ getInitialProps рдХреЗ рдЕрдВрджрд░ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ ..
рд╣рд╛рдБ, рдХреБрдЫ рджрд┐рдиреЛрдВ рдХреЗ рдЕрдкрдиреЗ рдкреНрд░рдпрд╛рд╕ рдХреЗ рд╕рд╛рде рджреМрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдЕрдЬреАрдм рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЬрд┐рди рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд╡реЗ рд╣реИрдВ:
@sentry/browser
рдФрд░ рдПрд╕рдПрд╕рдЖрд░ рдХреЗ рд▓рд┐рдП @sentry/node
рдЖрдпрд╛рдд рдХрд░рдирд╛рдореИрдВ #1
рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд▓рд╕реА рдЖрдпрд╛рдд рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреА рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ, рдХреБрдЫ рдРрд╕рд╛
const sentryInitialized = false;
# Inside some trigger point
const Sentry = ssr ? eval(`require('@sentry/node')`) : eval(`require('@sentry/browser')`);
if (!sentryInitialized) {
Sentry.init({dsn: SENTRY_DSN});
}
Sentry.captureException(err);
рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдиреЗрдХреНрд╕реНрдЯ рдХреЗ рдбрд╛рдпрдирд╛рдорд┐рдХ рдЗрдВрдкреЛрд░реНрдЯ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрднреА рддрдХ рдЙрдирд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред рдореБрдЭреЗ рдпрд╣ рднреА рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рд░ рдмрд╛рд░ рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдХреЛрдб рдЯреНрд░рд┐рдЧрд░ рд╣реЛрдиреЗ рдкрд░ require
рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдЕрд╕рд░ рдкрдбрд╝рддрд╛ рд╣реИред рдЕрдЧрд░ рдореИрдВ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рддрд╛ рд╣реВрдВ рддреЛ рдореИрдВ рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛ред
рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрд╕рдорд╕реНрдпрд╛ #2
, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рд╣реИрдВ:
_app.componentDidCatch
, рдЬреЛ SSR рдХреЗ рд▓рд┐рдП рд╕рдХреНрд░рд┐рдп рдирд╣реАрдВ рд╣реИ_error.getInitialProps
, рдЬрд┐рд╕рдореЗрдВ рдмрд╣реБрдд рд╕реА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВрдореЗрд░реА рдЖрдВрдд рдХреА рднрд╛рд╡рдирд╛ рдпрд╣ рд╣реИ рдХрд┐ рдиреЗрдХреНрд╕реНрдЯ рд╕реЗ рдкрд╣рд▓реЗ рд╕реЗрдВрдЯреНрд░реА рдХреЗ рдПрд░рд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдХреЗ рд╕рд░реНрд╡рд░ рдкрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрднреА рддрдХ рдирд╣реАрдВ рджрд┐рдпрд╛ рд╣реИред
рдлрд┐рд▓рд╣рд╛рд▓, рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдЖрдкрдХреА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓рд╛ рдХреЛрдИ рд╣реБрдХ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд░ рд╣рдордиреЗ рдкрд╛рдпрд╛ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ
рдПрдХ рдЬреЛрдЦрд┐рдо рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд▓рд╛ рдмрд╣реБрдд рдЬрд▓реНрджреА рдкрдХрдбрд╝рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ред
@mcdougal рдЖрд╣ &#!% рдореИрдВ рдмрд╣реБрдд рдЦреБрд╢ рдерд╛ рдЬрдм рдЖрдкрдХрд╛ рдХрд╛рдордХрд╛рдЬ рд╣рдореЗрдВ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдВрддрд░реА рдХреНрд▓рд╛рдЗрдВрдЯ/рд╕рд░реНрд╡рд░ рдХрд╡рд░реЗрдЬ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рдерд╛ред
рдореЗрд░реА рдкреВрд░реА рдЕрдЬреНрдЮрд╛рдирддрд╛ рдХреЛ рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдиреЛрдбрдЬ рд╕рдВрддрд░реА рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдкрд╣рд▓рд╛ рдмрди рдЬрд╛рдП? next.config.js рдореЗрдВ рдХреБрдЫ рдзреНрд╡рдЬ "disableErrorHandler" рдХрд╣рд▓рд╛рддреЗ рд╣реИрдВ?
@Enalmada рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдк рдЕрдЧрд▓рд╛ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╣ рд╣реЛрдЧрд╛ рдЬреЛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддреНрд░реБрдЯрд┐ рдкреГрд╖реНрда рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рдЖрдк рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдЕрдиреНрдп рдорд┐рдбрд▓рд╡реЗрдпрд░ рдбрд╛рд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЗрд╕реЗ рдЖрдЬрдорд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред
рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдЙрд╕ рдирд┐рд╢реНрдЪрд┐рдд рдХреЗ рд╕рд╛рде, рдореБрдЭреЗ рдЕрднреА рднреА рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рддрд░рд╣ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╕рд╛рде рд╣реА рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ :(
рдпрд╣ рдкреВрд░рд╛ рдореБрджреНрджрд╛ рд╢рд░реНрдо рдХреА рдмрд╛рдд рд╣реИ рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЕрдЧрд▓рд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╡рд░реЛрдзрдХ рд╣реИред
FYI рдХрд░реЗрдВ рдореИрдВ рд╣рд░ рдЬрдЧрд╣ @sentry/node
рдЖрдпрд╛рдд рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ next.config.js рдореЗрдВ рдбрд╛рд▓рддрд╛ рд╣реВрдВ:
if (!isServer) {
config.resolve.alias['@sentry/node$'] = '@sentry/browser'
}
рдЬреЛ @mcdougal . рдХреЗ eval
рд╕реЗ рдмреЗрд╣рддрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ
рдХрд╕реНрдЯрдо _app рдШрдЯрдХ рдФрд░ рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореЗрд░реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдиреЛрдЯреНрд╕ рдпрд╣рд╛рдВ рджрд┐рдП рдЧрдП рд╣реИрдВ:
_app.js
рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рднреА рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ _error.js
рдпрд╛ 404 рдЬреИрд╕реЗ рдкреГрд╖реНрда рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм ctx.err
рдЗрд╕реЗ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред_error.js
getInitialProps рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХреЗрдЧрд╛ ( ctx.err
рдореМрдЬреВрдж рд╣реЛрдиреЗ рдкрд░ рднреА рдЗрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ)class MyApp extends App {
static async getInitialProps (appContext) {
const { Component, ctx } = appContext
if (ctx.err) {
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { error: true, pageProps }
}
// here code that can throw an error, and then:
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
render() {
if (this.props.error) return super.render()
// rest of code that can throw an error
}
}
рдЕрдм рддрдХ рдореБрдЭреЗ рдЕрдЧрд▓реА.рдЬреЗрдПрд╕ рдореЗрдВ рдПрдХ рдмрд╣реБрдд рд╣реА рдирд╛рдЬреБрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдареАрдХ рд╕реЗ рд╕реЗрдЯ рдЕрдк рдорд┐рд▓ рд░рд╣реА рд╣реИ :(
рдзрдиреНрдпрд╡рд╛рдж @sheerun рдЬреЛ рд╕рд╣реА рджрд┐рд╢рд╛ рдХреА рдУрд░ рдПрдХ рдЕрдЪреНрдЫрд╛ рдкрдбрд╝рд╛рд╡ рд▓рдЧрддрд╛ рд╣реИред рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдЕрдЧрд▓реЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдЕрднреА рдЗрд╖реНрдЯрддрдо рдирд╣реАрдВ рд╣реИ, рдХреБрдЫ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рдореЙрдбреНрдпреВрд▓/рдорд┐рдбрд▓рд╡реЗрдпрд░ рдЬреЛрдбрд╝реЗ рдЧрдП рджреЗрдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рд╣рдо рдЗрд╕ рдкрд░ рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдЖрджрд┐ рдЬреЛрдбрд╝ рд╕рдХреЗрдВред
рд╕рдВрддрд░реА рдЬреИрд╕реЗ рдЖрдЗрд╕реЛрдореЛрд░реНрдлрд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдХрдореА рднреА рдЪреАрдЬреЛрдВ рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛ рд░рд╣реА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рд╕рд░рд▓ рдЖрдпрд╛рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдЗрд╕реЗ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдореЗрд╢рд╛ рдпрд╣ рдЬрд╛рдВрдЪрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рддреНрд░реБрдЯрд┐ рд╕рд░реНрд╡рд░ рдпрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рддрд░рдл рдЙрдард╛рдИ рдЧрдИ рд╣реИ рдпрд╛ рдирд╣реАрдВред
рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рд╣реИ? рдореИрдВрдиреЗ рдЕрдм рддрдХ рдЬреЛ рдХреЛрд╢рд┐рд╢ рдХреА рд╡рд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ: рдореИрдВрдиреЗ рдЕрдкрдирд╛ рд╕рднреА рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЛрдб _app.js . рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ
constructor(args: any) {
super(args)
Sentry.init({
dsn: 'blah',
environment: 'local',
})
Sentry.configureScope(scope => {
scope.setTag('errorOrigin', isServer ? 'SSR' : 'Client')
})
}
static async getInitialProps({ Component, router, ctx }: any) {
let pageProps = {}
try {
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
} catch (error) {
// console.log('we caught an error')
console.log(error)
Sentry.captureException(error)
throw error
}
return { pageProps }
}
рд╕рд╛рде рдореЗрдВ @sheerun рд╕реЗ рдЕрдЧрд▓рд╛ . рд╕рд░реНрд╡рд░ рдореЗрдВ рд╕рдВрддрд░реА рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рднреА if (!isServer) {
config.resolve.alias['@sentry/node$'] = '@sentry/browser'
}
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд╕рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░ рдХреЗ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдмрд╛рдж рдореЗрдВ рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рдкрд╛рд╕ рд▓реЙрдЧ рдореЗрдВ рдХреЛрдИ рд╕рд┐рдВрдереЗрдЯрд┐рдХ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВред
рдлрд┐рд░ рднреА рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЪреВрдВрдХрд┐ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдмрд╛рд░ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ, рдпрд╣ рдЕрднреА рднреА рдЕрдиреБрдкрдпреЛрдЧреА рд╣реИред
рдореИрдВрдиреЗ рдЗрд╕ рднрд╛рдЧ рдХреЛ рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рд╕реЗ рднреА рдЬреЛрдбрд╝рд╛ рд╣реИ
componentDidCatch(error: any, errorInfo: any) {
// if (process.env.FIAAS_NAMESPACE !== undefined) {
Sentry.configureScope(scope => {
Object.keys(errorInfo).forEach(key => {
scope.setExtra(key, errorInfo[key])
})
})
Sentry.captureException(error)
console.log('componentDidCatch')
// This is needed to render errors correctly in development / production
super.componentDidCatch(error, errorInfo)
// }
}
рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдкреВрд░рд╛ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдореБрджреНрджреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╕рд╛рде рд╣реА рдЖрдкрдХреЛ рд╕рдВрддрд░реА рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
_app.js рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд▓реЗрдХрд┐рди рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдмрд╛рд╣рд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ
рдмреБрдз, рдирд╡рдореНрдмрд░ 21, 2018 рдкрд░ abraxxas 2:53 pm рдкрд░ [email protected] рд▓рд┐рдЦрд╛ рд╣реИ:
рдХреНрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдХреЛрдИ рдЕрдкрдбреЗрдЯ рд╣реИ? рдореИрдВрдиреЗ рдЕрдм рддрдХ рдЬреЛ рдХреЛрд╢рд┐рд╢ рдХреА рд╡рд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ: I
рд╣рдорд╛рд░реЗ рд╕рднреА рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЛрдб рдХреЛ _app.js . рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛`
рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ (рддрд░реНрдХ: рдХреЛрдИ рднреА) {
рд╕реБрдкрд░ (рддрд░реНрдХ)
рд╕рдВрддрд░реА.рдЗрдирд┐рдЯ({
рдбреАрдПрд╕рдПрди: 'рдмреНрд▓рд╛рд╣',
рдкрд░реНрдпрд╛рд╡рд░рдг: 'рд╕реНрдерд╛рдиреАрдп',
})
рд╕рдВрддрд░реА.рдХреЙрдиреНрдлрд╝рд┐рдЧрд░рд╕реНрдХреЛрдк (рджрд╛рдпрд░рд╛ => {
рд╕реНрдХреЛрдк.рд╕реЗрдЯрдЯреИрдЧ ('рдПрд░рд░рдСрд░рд┐рдЬрд┐рди', рдЖрдИрд╕рд░реНрд╡рд░? 'рдПрд╕рдПрд╕рдЖрд░': 'рдХреНрд▓рд╛рдЗрдВрдЯ')
})
}рд╕реНрдереИрддрд┐рдХ async getInitialProps ({рдШрдЯрдХ, рд░рд╛рдЙрдЯрд░, ctx}: рдХреЛрдИ рднреА) {
рдЪрд▓реЛ рдкреЗрдЬрдкреНрд░реЙрдкреНрд╕ = {}try { if (Component.getInitialProps) { pageProps = await Component.getInitialProps(ctx) } } catch (error) { // console.log('we caught an error') console.log(error) Sentry.captureException(error) throw error } return { pageProps }
}
`
@sheerun . рд╕реЗ next.config.js рдЬреЛрдбрд╝ рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░
https://github.com/sheerun рдФрд░ рд╕рд░реНрд╡рд░ рдореЗрдВ рд╕рдВрддрд░реА рдкреНрд░рд╛рд░рдВрдн рдХрд░рдирд╛ред рдЬреЗрдПрд╕ рднреА рдЕрдЧрд░
(!isServer) { config.resolve.alias['@sentry/node$'] = '@sentry/browser' }
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд╕рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛрддрд╛ рд╣реИ
рд╕рд░реНрд╡рд░ред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдмрд╛рдж рдореЗрдВ рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╕рд╛рде рд╣реА
рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрд░реЗ рдкрд╛рд╕ рд▓реЙрдЧ рдореЗрдВ рдХреЛрдИ рд╕рд┐рдВрдереЗрдЯрд┐рдХ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВредрдлрд┐рд░ рднреА рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЪреВрдВрдХрд┐ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдЯреНрд░реИрдХрд┐рдВрдЧ рд╣реИ
рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдмрд╛рд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдпрд╣ рдЕрднреА рднреА рдЕрдиреБрдкрдпреЛрдЧреА рд╣реИред-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/zeit/next.js/issues/1852#issuecomment-440668980 , рдпрд╛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
рд╕реВрддреНрд░
https://github.com/notifications/unsubscribe-auth/AAR2DeIhoOj6PdWRA2VqiEZyrO5Jui8vks5uxVrHgaJpZM4NOQlp
.
рдореИрдВрдиреЗ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╛рд╣рд░ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рдЕрднреА рднреА рд╡рд╣реА рд╡реНрдпрд╡рд╣рд╛рд░ред @sheerun рдХреНрдпрд╛ рдЖрдк рд╢рд╛рдпрдж рдЕрдкрдиреЗ рд╕реЗрдЯрдЕрдк рдХрд╛ рдиреНрдпреВрдирддрдо рд╕рд╛рд░ рдкреЛрд╕реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдореИрдВрдиреЗ рдЗрд╕реЗ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд╕рд╛рде рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдФрд░ рдореИрдВ рдЗрд╕реЗ рдХрд╛рдо рдкрд░ рдирд╣реАрдВ рд▓рд╛ рд╕рдХрддрд╛ред рдЬреЛ рдХреБрдЫ рдореИрдВ рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рдерд╛ рдЙрд╕рдХреЗ рд▓рд┐рдП рдкреВрд░реА рдмрд╛рдд рдЕрддреНрдпрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд▓рдЧрддреА рд╣реИ :( рдХреНрдпрд╛ рдЖрдк рд╕рд░реНрд╡рд░ рдкрд░ рд╕рдВрддрд░реА рд╢реБрд░реВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдпрд╛ рдХреЗрд╡рд▓ рдХрдХреНрд╖рд╛ рдХреЗ рдмрд╛рд╣рд░ _app.js рдореЗрдВ рд╣реИрдВ?
рдореИрдВ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рдВрддрд░реА рдЙрджрд╛рд╣рд░рдг рдЕрдкрдбреЗрдЯ рдХрд░реВрдВрдЧрд╛ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдбрд░ рд╣реИ рдХрд┐ рдЗрд╕реЗ "рдмрд╣реБрдд рдЬрдЯрд┐рд▓" рдХреЗ рд░реВрдк рдореЗрдВ рдЦрд╛рд░рд┐рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЬрдм рдореБрдЭреЗ рд╕рдордп рдорд┐рд▓реЗрдЧрд╛ рддреЛ рдореИрдВ рдХреБрдЫ рдкреЛрд╕реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ ..
@sheerun рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рднреА рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рд▓рдп рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдпрджрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреНрдпреВрдирддрдо рдЬрдЯрд┐рд▓рддрд╛ рд╣реИ рдЬреЛ рд╕рдВрддрд░реА ssr рдХреЛ SyntheticErrors рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░рдиреЗ рдпрд╛ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рд╕рд░реНрд╡рд░ рддреНрд░реБрдЯрд┐ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╣рд╛рдВ рд╕реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдиреЗрдХреНрд╕реНрдЯрдЬ рдХреЛрд░ рд╕реБрдзрд╛рд░ рдпрд╛ рд╕рдВрддрд░реА рдЖрдЗрд╕реЛрдореЛрд░реНрдлрд┐рдХ рд╕рдорд░реНрдерди рдкрд░ рдЬреЛрд░ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣рд╛рдБ рдпрд╣ рдЬрд╛рддрд╛ рд╣реИ .. https://github.com/zeit/next.js/pull/5727
рддреЛ рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рдЬрдЯрд┐рд▓ рдХрд╛рдордХрд╛рдЬреА рдЙрджрд╛рд╣рд░рдг рд╣реИ, рддреЛ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реБрдзрд╛рд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ рдХрджрдо рдХреНрдпрд╛ рд╣реИрдВ:
next.js рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИ, рд╡рд╣ рд╣реИ next.config.js рдореЗрдВ рдХрд╕реНрдЯрдо рдорд┐рдбрд▓рд╡реЗрдпрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдФрд░ рдпреВрдирд┐рд╡рд░реНрд╕рд▓ (рдЖрдЗрд╕реЛрдореЛрд░реНрдлрд┐рдХ) рдкреНрд▓рдЧрдЗрди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП next.browser.js рдЬреИрд╕рд╛ рдХреБрдЫ (next.config.js рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡реЗрдмрдкреИрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реЛрдВ рдХреЗ рдмреАрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрд░рд┐рдкрддреНрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдХрд╛рд░рдг рд╣реЛрдЧрд╛)ред
next.browser.js рдХреЗ рд▓рд┐рдП next.js рдРрдк рдпрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдХреЛрд░реЗрдЯрд░ рдЬреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рдкреНрд▓рдЧрдЗрди рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрддрд░реА рдПрдХреАрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред
рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЯрд┐рдХрдЯ рд╣реИ рдпрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @timneutkens рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдЧрд▓реЗ рд╕рд░реНрд╡рд░ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреИрдХреЗрдЬреЛрдВ рдореЗрдВ
module.exports = {
server: server => {
server.use(Sentry.Handlers.errorHandler())
}
}
рдореИрдВрдиреЗ рдРрд╕реЗ рдПрдкреАрдЖрдИ рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ #6922 . рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ
рдпрд╣ рдХрд╕реНрдЯрдо рд╕рд░реНрд╡рд░ рдХреЛрдб рдореЗрдВ рдбреЗрдХреЛрд░реЗрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреБрдмрдВрдз рдХреЛ рдПрдХ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ .listen()
рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ next.js рдХреЛ рддрддреНрдХрд╛рд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕реЗ рдФрд░ рд╕рдЬрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
рдореБрдЭреЗ with-sentry
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдмрд╣реБрдд рдкрд░реЗрд╢рд╛рдиреА рд╣реЛ рд░рд╣реА рдереА, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдкреАрдЖрд░ рдЦреЛрд▓рд╛ред рдЗрд╕рдореЗрдВ рд╕рднреА рдШрдВрдЯрд┐рдпрд╛рдБ рдФрд░ рд╕реАрдЯреА рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред
рдЗрд╕реЗ рдХрд╕реНрдЯрдо _document.js
рдореЗрдВ рдЖрдЬрд╝рдорд╛рдПрдВ:
import React from "react";
import Document, {
Html,
Head,
Main,
NextScript,
} from "next/document";
import { NodeClient } from "@sentry/node";
const { default: getConfig } = require("next/config");
const { publicRuntimeConfig: { sentryDSN } } = getConfig();
let sentry = null;
if (sentryDSN) {
sentry = new NodeClient({ dsn: sentryDSN });
}
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
if (ctx.err && sentry) sentry.captureException(ctx.err);
return { ...initialProps };
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
рдФрд░ рдпрд╣ рдХрд╕реНрдЯрдо _app.js
:
import * as Sentry from "@sentry/browser";
const { default: getConfig } = require("next/config");
const { publicRuntimeConfig: { sentryDSN } } = getConfig();
if (sentryDSN) {
Sentry.init({ dsn: sentryDSN });
}
рдЗрд╕рд╕реЗ рдореБрдЭреЗ рдорджрдж рдорд┐рд▓рддреА рд╣реИред
рдЯреАрдмреАрдПрдЪ рдореИрдВ рдмрд╣реБрдд рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВ рдХрд┐ рдЕрдЧрд▓реЗ рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╕реНрдерд╛рди рдХреМрди рд╕реЗ рд╣реИрдВред рдЬреЗрдПрд╕ рдЕрднреА рд╣реИрдВред _app.tsx, _error.tsx рдФрд░ _document.tsx рд╣реИрдВ, рдХреБрдЫ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдХрд╣ рд░рд╣реА рд╣реИрдВ рдХрд┐ рдХреБрдЫ рд╕рд╛рдорд╛рди _error.tsx рдореЗрдВ рдкрдХрдбрд╝реЗ рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП (рдЬреИрд╕реЗ: https://github.com/zeit/next.js/pull/5727/files #r235981700) рд▓реЗрдХрд┐рди рд╡рд░реНрддрдорд╛рди рдЙрджрд╛рд╣рд░рдг рдпрд╛ рддреЛ _app.tsx рдпрд╛ _app рдФрд░ _document рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдореИрдВрдиреЗ рдЕрдм рджреЛрдиреЛрдВ рддрд░реАрдХреЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ ssr рдХреЗ рджреМрд░рд╛рди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреБрдЫ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдореЗрд░реЗ рд▓рд┐рдП рдкрдХрдбрд╝ рдореЗрдВ рдирд╣реАрдВ рдЖ рд░рд╣реА рд╣реИрдВред рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдЕрдм рдХреМрди рд╕реЗ рд╕реНрдерд╛рди рд╕рд╣реА рд╣реИрдВ? рдореЗрд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рддрд╛рд░реНрдХрд┐рдХ рдПрдХ _app рдХреЗ рдШрдЯрдХрдбрд┐рдбрдХреИрдЪ рдФрд░ _error рдХреЗ getInitialProps рдореЗрдВ рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдкрд░реЛрд╕рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдореИрдВ _рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рд╕рдВрдкреВрд░реНрдг process.on
рднрд╛рдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рд╣реВрдБ
рдХреНрдпрд╛ рдХреЛрдИ рдФрд░ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬреНрдЮрд╛рди рд░рдЦрдиреЗ рд╡рд╛рд▓рд╛ рдХреГрдкрдпрд╛ рдЗрд╕ рдкреНрд░рд╢реНрди рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?
@abraxxas process.on
рдореЗрдВ _document.js
рд╕рд░реНрд╡рд░ рдкрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝ рд░рд╣рд╛ рд╣реИред рдкреБрдирд░реНрдХрдерди рдХреЗ рд░реВрдк рдореЗрдВ,
_document.js
рдХреЗрд╡рд▓ _рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб_ рд╣реИ рдФрд░ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдорд╛рд░реНрдХрдЕрдк рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред_app.js
рдХреЗрд╡рд▓ _client-side_ рд╣реИ рдФрд░ рдкреГрд╖реНрдареЛрдВ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредрдЗрд╕рд▓рд┐рдП, рдЬрдм рд╕рд░реНрд╡рд░ рдкрд░ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ рддреЛ рдЙрд╕реЗ process.on
рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрддрд░реА рдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рдлрд┐рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рддреНрд░реБрдЯрд┐ рдкреГрд╖реНрда рдпрд╛ _error.js
рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛ред
рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕рд╕реЗ рдорджрдж рдорд┐рд▓реЗрдЧреА: https://leerob.io/blog/configuring-sentry-for-nextjs-apps/
_app.js рдХреЗрд╡рд▓ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ componentDidCatch
рд╣реИ
@timneutkens рдареАрдХ рд╣реИ, рдпрд╣ рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ ред рдХреНрдпрд╛ рдЖрдк рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ _app.js
рдХреЗрд╡рд▓ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдирд╣реАрдВ рд╣реИ?
@timneutkens рдХреНрдпрд╛ рдЖрдк рд╢рд╛рдпрдж рд╕рдордЭрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдХрд╣рд╛рдБ рдФрд░ рдХреНрдпреЛрдВ
@timneutkens рдареАрдХ рд╣реИ, рдпрд╣ рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ ред рдХреНрдпрд╛ рдЖрдк рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ
_app.js
рдХреЗрд╡рд▓ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдирд╣реАрдВ рд╣реИ?
рд╣реИрд▓реЛ рд▓реАрд░реЛрдм!
рдореИрдВрдиреЗ рдЕрднреА рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдорд░реНрдЬ рдЕрдиреБрд░реЛрдз рдкрд░ рдПрдХ рдкреНрд░рд╢реНрди рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рд╣реИ:
https://github.com/zeit/next.js/pull/7360#issuecomment -514318899
рдЙрд╕ рдкреНрд░рд╢реНрди рдХреЛ рдЬреЛрдбрд╝рдирд╛ ... рдореИрдВрдиреЗ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд░реЗрдВрдбрд░() рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреЗ рдХреА рднреА рдХреЛрд╢рд┐рд╢ рдХреА (рдореИрдВрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ raiseErrorInRender рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд┐рдпрд╛: рд╕рдЪ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓рд╛ рд░реЗрдВрдбрд░, рдЬреЛ рд╕рд░реНрд╡рд░ рдкрдХреНрд╖реАрдп рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧрд╛), рдФрд░ рд╡рд╣ рддреНрд░реБрдЯрд┐ рднреА рд╕рдВрддрд░реА рджреНрд╡рд╛рд░рд╛ рдХрдмреНрдЬрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рдХреНрдпрд╛ рд╡реЗ рд╕рд░реНрд╡рд░ рдкрдХреНрд╖реАрдп рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИрдВ? рдореИрдВ рдЕрдЧрд▓рд╛ 9 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред
рдпрджрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рд╣реИ, рдФрд░ рдХреЗрд╡рд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рддреЛ _document.js рдлрд╝рд╛рдЗрд▓ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
рдХрд┐рд╕реА рднреА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдЧреНрд░рд┐рдо рд░реВрдк рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж!
@timneutkens рдареАрдХ рд╣реИ, рдпрд╣ рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ ред рдХреНрдпрд╛ рдЖрдк рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ
_app.js
рдХреЗрд╡рд▓ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдирд╣реАрдВ рд╣реИ?
рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрддреЗ рд╣реБрдП, _app рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдкреГрд╖реНрдареЛрдВ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдРрдк рдШрдЯрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░реЗрдВрдЧреЗ рдЬреИрд╕реЗ рдкреГрд╖реНрда рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рд╕реНрдерд╛рдпреА рд▓реЗрдЖрдЙрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ (рд╕рднреА рдкреГрд╖реНрда рд╕рдорд╛рди _app рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ), рдпрд╛ рд░реЗрдбрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рддреЛ, рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓рд╛ рдкрд╣рд▓рд╛ рд░реЗрдВрдбрд░ рднреА _app рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛ (рдпрд╣ рдХреЗрд╡рд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдирд╣реАрдВ рд╣реИ)ред
рдЙрд╕ рдкреНрд░рд╢реНрди рдХреЛ рдЬреЛрдбрд╝рдирд╛ ... рдореИрдВрдиреЗ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд░реЗрдВрдбрд░() рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреЗ рдХреА рднреА рдХреЛрд╢рд┐рд╢ рдХреА (рдореИрдВрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ raiseErrorInRender рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд┐рдпрд╛: рд╕рдЪ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓рд╛ рд░реЗрдВрдбрд░, рдЬреЛ рд╕рд░реНрд╡рд░ рдкрдХреНрд╖реАрдп рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧрд╛), рдФрд░ рд╡рд╣ рддреНрд░реБрдЯрд┐ рднреА рд╕рдВрддрд░реА рджреНрд╡рд╛рд░рд╛ рдХрдмреНрдЬрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЙрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ? рдореИрдВрдиреЗ рдЗрд╕реЗ _error рдХреЗ getInitialProps рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрддрд░реА рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореБрдЭреЗ рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ (рдЬреНрдпрд╛рджрд╛рддрд░ рдЕрдЧрд░ рд╡реЗ рдПрдкреАрдЖрдИ рд╡рд┐рдлрд▓рддрд╛рдУрдВ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ) рддреЛ рд╡реЗ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рдирд╣реАрдВ рд╣реБрдЖ рд╣реВрдВред
рдЙрд╕ рдкреНрд░рд╢реНрди рдХреЛ рдЬреЛрдбрд╝рдирд╛ ... рдореИрдВрдиреЗ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд░реЗрдВрдбрд░() рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреЗ рдХреА рднреА рдХреЛрд╢рд┐рд╢ рдХреА (рдореИрдВрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ raiseErrorInRender рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд┐рдпрд╛: рд╕рдЪ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓рд╛ рд░реЗрдВрдбрд░, рдЬреЛ рд╕рд░реНрд╡рд░ рдкрдХреНрд╖реАрдп рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧрд╛), рдФрд░ рд╡рд╣ рддреНрд░реБрдЯрд┐ рднреА рд╕рдВрддрд░реА рджреНрд╡рд╛рд░рд╛ рдХрдмреНрдЬрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЙрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ? рдореИрдВрдиреЗ рдЗрд╕реЗ _error рдХреЗ getInitialProps рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрддрд░реА рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореБрдЭреЗ рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ (рдЬреНрдпрд╛рджрд╛рддрд░ рдЕрдЧрд░ рд╡реЗ рдПрдкреАрдЖрдИ рд╡рд┐рдлрд▓рддрд╛рдУрдВ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ) рддреЛ рд╡реЗ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рдирд╣реАрдВ рд╣реБрдЖ рд╣реВрдВред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдирд╣реАрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЬрд┐рд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рд╡рд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрджрд╛рд╣рд░рдг (рдУрд╡рд░рд░рд╛рдЗрдб _document.js рдлрд╝рд╛рдЗрд▓ рдХреЛ рдШрдЯрд╛рдХрд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╡рд╣реА рд╣реИрдВ рдЬрд┐рди рдкрд░ рдореЗрд░рд╛ рдХреЛрдИ рдирд┐рдпрдВрддреНрд░рдг рдФрд░ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗрдВ, рдЬрдм рддрдХ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдореБрдЭреЗ рд░рд┐рдкреЛрд░реНрдЯ рди рдХрд░реЗрдВред рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХрд┐рд╕реА рднреА рд▓реЙрдЧ рд▓рд╛рдЗрди рдХреЛ рд╕реАрдзреЗ рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░ рджреВрдВрдЧрд╛ред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╕рднреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ рдореБрдЭреЗ рдХрдо рд╕реЗ рдХрдо рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдЧреА рдЬреЛ рдЖрд╡реЗрджрди рдкрд░ рд╣реЛ рд╕рдХрддреА рд╣реИред
рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдЦрд╝рдпрд╛рд▓ рд╣реИ? рдзрдиреНрдпрд╡рд╛рдж!
рдЙрд╕ рдкреНрд░рд╢реНрди рдХреЛ рдЬреЛрдбрд╝рдирд╛ ... рдореИрдВрдиреЗ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд░реЗрдВрдбрд░() рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрдиреЗ рдХреА рднреА рдХреЛрд╢рд┐рд╢ рдХреА (рдореИрдВрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ raiseErrorInRender рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд┐рдпрд╛: рд╕рдЪ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓рд╛ рд░реЗрдВрдбрд░, рдЬреЛ рд╕рд░реНрд╡рд░ рдкрдХреНрд╖реАрдп рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧрд╛), рдФрд░ рд╡рд╣ рддреНрд░реБрдЯрд┐ рднреА рд╕рдВрддрд░реА рджреНрд╡рд╛рд░рд╛ рдХрдмреНрдЬрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЙрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ? рдореИрдВрдиреЗ рдЗрд╕реЗ _error рдХреЗ getInitialProps рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрддрд░реА рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореБрдЭреЗ рд╕рд░реНрд╡рд░ рдкрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ (рдЬреНрдпрд╛рджрд╛рддрд░ рдЕрдЧрд░ рд╡реЗ рдПрдкреАрдЖрдИ рд╡рд┐рдлрд▓рддрд╛рдУрдВ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реИрдВ) рддреЛ рд╡реЗ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рдирд╣реАрдВ рд╣реБрдЖ рд╣реВрдВред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдирд╣реАрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЬрд┐рд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рд╡рд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдкрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрджрд╛рд╣рд░рдг (рдУрд╡рд░рд░рд╛рдЗрдб _document.js рдлрд╝рд╛рдЗрд▓ рдХреЛ рдШрдЯрд╛рдХрд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╡рд╣реА рд╣реИрдВ рдЬрд┐рди рдкрд░ рдореЗрд░рд╛ рдХреЛрдИ рдирд┐рдпрдВрддреНрд░рдг рдФрд░ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗрдВ, рдЬрдм рддрдХ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдореБрдЭреЗ рд░рд┐рдкреЛрд░реНрдЯ рди рдХрд░реЗрдВред рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХрд┐рд╕реА рднреА рд▓реЙрдЧ рд▓рд╛рдЗрди рдХреЛ рд╕реАрдзреЗ рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░ рджреВрдВрдЧрд╛ред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╕рднреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ рдореБрдЭреЗ рдХрдо рд╕реЗ рдХрдо рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдЧреА рдЬреЛ рдЖрд╡реЗрджрди рдкрд░ рд╣реЛ рд╕рдХрддреА рд╣реИред
рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдЦрд╝рдпрд╛рд▓ рд╣реИ? рдзрдиреНрдпрд╡рд╛рдж!
рдареАрдХ рдпрд╣реА рд╣рдо рдЕрднреА рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрдЯрдкрдЯрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣рдо рд╕рд╛рдордиреЗ рдЖ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдХреБрдЫ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдВрддрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрддрд░реА рдпрд╛ рдЕрдЧрд▓реЗ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдЪрд▓ рд░рд╣рд╛ рд╣реЛрдЧрд╛ред рдореИрдВрдиреЗ рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рджреЛрдиреЛрдВ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдФрд░ рд╡реЗ рджреЛрдиреЛрдВ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рд╣рдж рддрдХ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣рдорд╛рд░реЗ рд╕реЗрдЯрдЕрдк рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИ
рдЗрд╕ рдереНрд░реЗрдб рдХреЗ рд▓реЛрдЧреЛрдВ рдХреА рджрд┐рд▓рдЪрд╕реНрдкреА https://github.com/zeit/next.js/pull/8684 рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдмрдЧреНрд╕ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЗрд╕рдореЗрдВ рд╣реИрдВрдбрд▓ рди рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ 12 рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ Next.js рдЖрдкрдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рдХреНрдпрд╛ рдирд╣реАрдВред
рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЦрдмрд░?
рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИ redux
рдиреЛрдб рдмрдЪрд╛рдиреЗ рдореЗрдВ рдбреЗрдЯрд╛ рддреНрд░реБрдЯрд┐ рд▓рд╛рдиреЗ state
рддреЛ рдлрд┐рд░ рдореЗрдВ componentDidMount
рдХреЗ _app.js
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдпрд╛ рдкреЛрд╕реНрдЯ рддреНрд░реБрдЯрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХреБрдЫ (рдЪреЗрддрд╛рд╡рдиреА рдмреИрдХрдПрдВрдб рдХреЗ рд▓рд┐рдП)ред
рдХреЛрдб рд╡рд╣рд╛рдБ рд╣реИ next-antd-scaffold_server-error ред
========> рд░рд╛рдЬреНрдп
import {
SERVER_ERROR,
CLEAR_SERVER_ERROR
} from '../../constants/ActionTypes';
const initialState = {
errorType: []
};
const serverError = (state = initialState, { type, payload }) => {
switch (type) {
case SERVER_ERROR: {
const { errorType } = state;
errorType.includes(payload) ? null : errorType.push(payload);
return {
...state,
errorType
};
}
case CLEAR_SERVER_ERROR: {
return initialState;
}
default:
return state;
}
};
export default serverError;
=======> рдХреНрд░рд┐рдпрд╛
import {
SERVER_ERROR
} from '../../constants/ActionTypes';
export default () => next => action => {
if (!process.browser && action.type.includes('FAIL')) {
next({
type: SERVER_ERROR,
payload: action.type
});
}
return next(action);
};
=======> _app.js
...
componentDidMount() {
const { store: { getState, dispatch } } = this.props;
const { errorType } = getState().serverError;
if (errorType.length > 0) {
Promise.all(
errorType.map(type => message.error(`Node Error, Codeя╝Ъ${type}`))
);
dispatch(clearServerError());
}
}
...
https://github.com/zeit/next.js/issues/1852#issuecomment -353671222 рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рдореБрдЭреЗ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд░реЛрд▓рдмрд╛рд░ рддреНрд░реБрдЯрд┐ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ
_рдЕрдиреЛрд░реНрдЯреЛрдбреЙрдХреНрд╕_рд╕рдорд╛рдзрд╛рдиреЛрдВ рд╕реЗ рдкреНрдпрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
function installErrorHandler(app) { const _renderErrorToHTML = app.renderErrorToHTML.bind(app) const errorHandler = rollbar.errorHandler() app.renderErrorToHTML = (err, req, res, pathname, query) => { if (err) { errorHandler(err, req, res, () => {}) } return _renderErrorToHTML(err, req, res, pathname, query) } return app } // ┬п\_(уГД)_/┬п
рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ 404 рддреНрд░реБрдЯрд┐ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рддреНрд░реБрдЯрд┐ рддрд░реНрдХ 404 рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рд╢реВрдиреНрдп рд╣реЛрдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред
рдореИрдВрдиреЗ рдЗрд╕реЗ рдЗрд▓рд╛рд╕реНрдЯрд┐рдХ рдПрдкреАрдПрдо рдиреЛрдб рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд╣рд▓ рдХрд┐рдпрд╛ (https://www.npmjs.com/package/elastic-apm-node)
рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП:
next.config.js
:
webpack: (config, { isServer, webpack }) => {
if (!isServer) {
config.node = {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
};
// ignore apm (might use in nextjs code but dont want it in client bundles)
config.plugins.push(
new webpack.IgnorePlugin(/^(elastic-apm-node)$/),
);
}
return config;
}
рдлрд┐рд░ _error.js
func рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ рдЖрдк рдХреИрдкреНрдЪрд░ рдПрд░рд░ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
function Error({ statusCode, message, err }) {
const serverSide = typeof window === 'undefined';
// only run this on server side as APM only works on server
if (serverSide) {
// my apm instance (imports elastic-apm-node and returns captureError)
const { captureError } = require('../src/apm');
if (err) {
captureError(err);
} else {
captureError(`Message: ${message}, Status Code: ${statusCode}`);
}
}
}
рд╕рднреА рдХреЛ рдкреНрд░рдгрд╛рдо! рд╣рдордиреЗ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╕рд░реНрд╡рд░ рдХреЛ рдЬреЛрдбрд╝реЗ рдмрд┐рдирд╛ рдиреЗрдХреНрд╕реНрдЯ.рдЬреЗрдПрд╕ рдореЗрдВ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╕реНрдЯрд╛рдЗрд▓ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдирдкреАрдПрдо рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓реЙрдиреНрдЪ рдХреА рд╣реИред рдпрд╣ рдЖрдкрдХреЗ рд╕рд░реНрд╡рд░ рддреНрд░реБрдЯрд┐ рдкреНрд░рдмрдВрдзрди рдЪреБрдиреМрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ! рдпрджрд┐ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рддреЛ рдЗрд╕реЗ рджреЗрдЦреЗрдВред https://github.com/oslabs-beta/connext-js
рдХрд┐рд╕реА рдХреЛ рднреА getServerSideProps
рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ (рдФрд░ рд╕рдВрднрд╛рд▓рдиреЗ) рдореЗрдВ рд╕рдлрд▓рддрд╛ рдорд┐рд▓реА рд╣реИ?
рдХрд┐рд╕реА рдХреЛ рднреА
getServerSideProps
рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ (рдФрд░ рд╕рдВрднрд╛рд▓рдиреЗ) рдореЗрдВ рд╕рдлрд▓рддрд╛ рдорд┐рд▓реА рд╣реИ?
рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдврд╛рдВрдЪрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рджреЛрдиреЛрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд▓реЙрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдореБрд╣рд╛рд╡рд░реЗрджрд╛рд░ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ тАНтЩВя╕П
рдХрд┐рд╕реА рдХреЛ рднреА
getServerSideProps
рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ (рдФрд░ рд╕рдВрднрд╛рд▓рдиреЗ) рдореЗрдВ рд╕рдлрд▓рддрд╛ рдорд┐рд▓реА рд╣реИ?
@stephankaag
рд╣рд╛рдБ, рдРрд╕рд╛ рдХреБрдЫ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
рдХреНрд░реИрд╢ рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдПрдХ рдорд┐рдбрд▓рд╡реЗрдпрд░ рдмрдирд╛рдПрдВред рдореИрдВрдиреЗ Sentry
рдХреЛ CrashReporter
рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░ рд▓рдкреЗрдЯ рд▓рд┐рдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдХреЗрд╡рд▓ Sentry
рд▓реМрдЯрдиреЗ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдЪрд▓реЗрдЧрд╛ (рдпрд╛рдиреА req.getCrashReporter = () => Sentry
)ред
// crash-reporter.js
const Sentry = require("@sentry/node");
class CrashReporter {
constructor(){
Sentry.init({ dsn: process.env.SENTRY_DSN });
}
captureException(ex){
return Sentry.captureException(ex);
}
}
function crashReporterMiddleware(req, res, next) {
req.getCrashReporter = () => new CrashReporter();
next();
}
module.exports = crashReporterMiddleware;
рдЕрдЧрд▓рд╛, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, Next.js рдЕрдиреБрд░реЛрдз рд╣реИрдВрдбрд▓рд░ рд╕реЗрдЯ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЕрдкрдиреЗ рдРрдк рдореЗрдВ рдорд┐рдбрд▓рд╡реЗрдпрд░ рд▓реЛрдб рдХрд░реЗрдВ:
// server.js
const crashReporterMiddleware = require("./middleware/crash-reporter")
...
app.use(crashReporterMiddleware);
...
setHandler((req, res) => {
return handle(req, res);
});
рдлрд┐рд░ рдЖрдк рдЬрд╣рд╛рдВ рдХрд╣реАрдВ рднреА рдХреЙрд▓ рдХрд░реЗрдВ getServerSideProps
:
// _error.js
export async function getServerSideProps({req, res, err}) {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
const crashReporter = req.getCrashReporter();
const eventId = crashReporter.captureException(err);
req.session.eventId = eventId;
return {
props: { statusCode, eventId }
}
}
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
_рдЕрдиреЛрд░реНрдЯреЛрдбреЙрдХреНрд╕_рд╕рдорд╛рдзрд╛рдиреЛрдВ рд╕реЗ рдкреНрдпрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП