Merge pull request #4283 from omnivore-app/fix/web-setup-sentry

Setup sentry for web code
This commit is contained in:
Jackson Harper
2024-08-22 11:32:42 +08:00
committed by GitHub
9 changed files with 98 additions and 50 deletions

View File

@ -37,3 +37,6 @@ yarn-error.log*
/storybook-static/ /storybook-static/
# Sentry # Sentry
.sentryclirc .sentryclirc
# Sentry Config File
.env.sentry-build-plugin

View File

@ -0,0 +1,5 @@
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./sentry.server.config')
}
}

View File

@ -1,13 +1,13 @@
const ContentSecurityPolicy = ` const ContentSecurityPolicy = `
default-src 'self'; default-src 'self';
base-uri 'self'; base-uri 'self';
connect-src 'self' ${process.env.NEXT_PUBLIC_SERVER_BASE_URL} https://proxy-prod.omnivore-image-cache.app https://accounts.google.com https://proxy-demo.omnivore-image-cache.app https://storage.googleapis.com https://widget.intercom.io https://api-iam.intercom.io https://static.intercomassets.com https://downloads.intercomcdn.com https://platform.twitter.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io wss://nexus-europe-websocket.intercom.io wss://nexus-australia-websocket.intercom.io https://uploads.intercomcdn.com https://tools.applemediaservices.com wss://www.tiktok.com; connect-src 'self' ${process.env.NEXT_PUBLIC_SERVER_BASE_URL} https://proxy-prod.omnivore-image-cache.app https://accounts.google.com https://proxy-demo.omnivore-image-cache.app https://storage.googleapis.com https://widget.intercom.io https://api-iam.intercom.io https://static.intercomassets.com https://downloads.intercomcdn.com https://platform.twitter.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io wss://nexus-europe-websocket.intercom.io wss://nexus-australia-websocket.intercom.io https://uploads.intercomcdn.com https://tools.applemediaservices.com wss://www.tiktok.com *.sentry.io;
font-src 'self' data: https://cdn.jsdelivr.net https://js.intercomcdn.com https://fonts.intercomcdn.com; font-src 'self' data: https://cdn.jsdelivr.net https://js.intercomcdn.com https://fonts.intercomcdn.com;
form-action 'self' ${process.env.NEXT_PUBLIC_SERVER_BASE_URL} https://getpocket.com/auth/authorize https://intercom.help https://api-iam.intercom.io https://api-iam.eu.intercom.io https://api-iam.au.intercom.io https://www.notion.so https://api.notion.com; form-action 'self' ${process.env.NEXT_PUBLIC_SERVER_BASE_URL} https://getpocket.com/auth/authorize https://intercom.help https://api-iam.intercom.io https://api-iam.eu.intercom.io https://api-iam.au.intercom.io https://www.notion.so https://api.notion.com;
frame-ancestors 'none'; frame-ancestors 'none';
frame-src 'self' https://accounts.google.com https://platform.twitter.com https://www.youtube.com https://www.youtube-nocookie.com https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/ https://www.recaptcha.net https://www.tiktok.com; frame-src 'self' https://accounts.google.com https://platform.twitter.com https://www.youtube.com https://www.youtube-nocookie.com https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/ https://www.recaptcha.net https://www.tiktok.com;
manifest-src 'self'; manifest-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval' accounts.google.com https://widget.intercom.io https://js.intercomcdn.com https://platform.twitter.com https://cdnjs.cloudflare.com https://cdn.jsdelivr.net https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net https://www.gstatic.cn/ https://*.neutral.ttwstatic.com https://www.tiktok.com/embed.js; script-src 'self' 'unsafe-inline' 'unsafe-eval' accounts.google.com https://widget.intercom.io https://js.intercomcdn.com https://platform.twitter.com https://cdnjs.cloudflare.com https://cdn.jsdelivr.net https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net https://www.gstatic.cn/ https://*.neutral.ttwstatic.com https://www.tiktok.com/embed.js https://browser.sentry-cdn.com https://js.sentry-cdn.com;
style-src 'self' 'unsafe-inline' https://accounts.google.com https://cdnjs.cloudflare.com https://*.neutral.ttwstatic.com; style-src 'self' 'unsafe-inline' https://accounts.google.com https://cdnjs.cloudflare.com https://*.neutral.ttwstatic.com;
img-src 'self' blob: data: https:; img-src 'self' blob: data: https:;
worker-src 'self' blob:; worker-src 'self' blob:;
@ -249,3 +249,42 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true', enabled: process.env.ANALYZE === 'true',
}) })
module.exports = withBundleAnalyzer(moduleExports) module.exports = withBundleAnalyzer(moduleExports)
// Injected content via Sentry wizard below
const { withSentryConfig } = require('@sentry/nextjs')
module.exports = withSentryConfig(module.exports, {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
org: 'omnivore',
project: process.env.SENTRY_PROJECT,
// Only print logs for uploading source maps in CI
silent: !process.env.CI,
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
// This can increase your server load as well as your hosting bill.
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
// side errors will fail.
tunnelRoute: '/monitoring',
// Hides source maps from generated client bundles
hideSourceMaps: true,
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: true,
})

View File

@ -0,0 +1,23 @@
import { Button } from '../../components/elements/Button'
import {
BorderedFormInput,
FormLabel,
} from '../../components/elements/FormElements'
import { SpanBox, VStack } from '../../components/elements/LayoutPrimitives'
import { StyledText } from '../../components/elements/StyledText'
import { webBaseURL } from '../../lib/appConfig'
export default function DebugShareTarget(): JSX.Element {
return (
<Button
type="submit"
style="ctaDarkYellow"
css={{ my: '$2' }}
onClick={(event) => {
throw new Error('test error for sentry')
}}
>
Submit
</Button>
)
}

View File

@ -39,36 +39,7 @@ MyError.getInitialProps = async (context: any) => {
return errorInitialProps return errorInitialProps
} }
// Running on the server, the response object (`res`) is available. await Sentry.captureUnderscoreErrorException(context)
//
// Next.js will pass an err on the server if a page's data fetching methods
// threw or returned a Promise that rejected
//
// Running on the client (browser), Next.js will provide an err if:
//
// - a page's `getInitialProps` threw or returned a Promise that rejected
// - an exception was thrown somewhere in the React lifecycle (render,
// componentDidMount, etc) that was caught by Next.js's React Error
// Boundary. Read more about what types of exceptions are caught by Error
// Boundaries: https://reactjs.org/docs/error-boundaries.html
if (err) {
Sentry.captureException(err)
// Flushing before returning is necessary if deploying to Vercel, see
// https://vercel.com/docs/platform/limits#streaming-responses
await Sentry.flush(2000)
return errorInitialProps
}
// If this point is reached, getInitialProps was called without any
// information about what the error might be. This is unexpected and may
// indicate a bug introduced in Next.js, so record it in Sentry
Sentry.captureException(
new Error(`_error.js getInitialProps missing data at path: ${asPath}`)
)
await Sentry.flush(2000)
return errorInitialProps return errorInitialProps
} }

View File

@ -1,7 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next' import type { NextApiRequest, NextApiResponse } from 'next'
import { serialize } from 'cookie' import { serialize } from 'cookie'
import * as jwt from 'jsonwebtoken' import * as jwt from 'jsonwebtoken'
import { withSentry } from '@sentry/nextjs'
import { ssoJwtSecret } from '../../../lib/appConfig' import { ssoJwtSecret } from '../../../lib/appConfig'
import { DEFAULT_HOME_PATH } from '../../../lib/navigations' import { DEFAULT_HOME_PATH } from '../../../lib/navigations'
@ -37,4 +36,4 @@ const requestHandler = (req: NextApiRequest, res: NextApiResponse): void => {
res.end() res.end()
} }
export default withSentry(requestHandler) export default requestHandler

View File

@ -1,5 +1,4 @@
import type { NextApiRequest, NextApiResponse } from 'next' import type { NextApiRequest, NextApiResponse } from 'next'
import { withSentry } from '@sentry/nextjs'
import { serialize } from 'cookie' import { serialize } from 'cookie'
const requestHandler = (req: NextApiRequest, res: NextApiResponse): void => { const requestHandler = (req: NextApiRequest, res: NextApiResponse): void => {
@ -7,4 +6,4 @@ const requestHandler = (req: NextApiRequest, res: NextApiResponse): void => {
res.send('logged out') res.send('logged out')
} }
export default withSentry(requestHandler) export default requestHandler

View File

@ -1,15 +1,18 @@
// This file configures the initialization of Sentry on the client.
// The config you add here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from '@sentry/nextjs' import * as Sentry from '@sentry/nextjs'
import { sentryDSN } from './lib/appConfig' import { sentryDSN } from './lib/appConfig'
if (sentryDSN) { if (sentryDSN) {
Sentry.init({ Sentry.init({
dsn: sentryDSN, dsn: sentryDSN,
// We recommend adjusting this value in production, or using tracesSampler
// for finer control // Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1.0, tracesSampleRate: 1,
// ...
// Note: if you want to override the automatic release value, do not set a // Setting this option to true will print useful information to the console while you're setting up Sentry.
// `release` value here - use the environment variable `SENTRY_RELEASE`, so debug: false,
// that it will also get attached to your source maps
}) })
} }

View File

@ -1,15 +1,21 @@
// This file configures the initialization of Sentry on the server.
// The config you add here will be used whenever the server handles a request.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from '@sentry/nextjs' import * as Sentry from '@sentry/nextjs'
import { sentryDSN } from './lib/appConfig' import { sentryDSN } from './lib/appConfig'
if (sentryDSN) { if (sentryDSN) {
Sentry.init({ Sentry.init({
dsn: sentryDSN, dsn: sentryDSN,
// We recommend adjusting this value in production, or using tracesSampler
// for finer control // Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: 1.0, tracesSampleRate: 1,
// ...
// Note: if you want to override the automatic release value, do not set a // Setting this option to true will print useful information to the console while you're setting up Sentry.
// `release` value here - use the environment variable `SENTRY_RELEASE`, so debug: false,
// that it will also get attached to your source maps
// Uncomment the line below to enable Spotlight (https://spotlightjs.com)
// spotlight: process.env.NODE_ENV === 'development',
}) })
} }