build: 🏗️ Add Sentry to builder
This commit is contained in:
@ -44,3 +44,6 @@ STRIPE_WEBHOOK_SECRET=
|
||||
NEXT_PUBLIC_GIPHY_API_KEY=
|
||||
|
||||
NEXT_PUBLIC_VIEWER_HOST=http://localhost:3001
|
||||
|
||||
# (Optional) Error tracking with Sentry
|
||||
NEXT_PUBLIC_SENTRY_DSN=
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { OrderedList, ListItem, Tag, Text, Stack } from '@chakra-ui/react'
|
||||
import { OrderedList, ListItem, Tag } from '@chakra-ui/react'
|
||||
import { ChatEmbedCode } from 'components/share/codeSnippets/Chat/EmbedCode'
|
||||
import { ChatEmbedSettings } from 'components/share/codeSnippets/Chat/EmbedSettings'
|
||||
import { ContainerEmbedCode } from 'components/share/codeSnippets/Container/EmbedCode'
|
||||
|
14
apps/builder/next.config.js
Normal file
14
apps/builder/next.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { withSentryConfig } = require('@sentry/nextjs')
|
||||
|
||||
const moduleExports = {
|
||||
// Your existing module.exports
|
||||
}
|
||||
|
||||
const sentryWebpackPluginOptions = {
|
||||
silent: true,
|
||||
// For all available options, see:
|
||||
// https://github.com/getsentry/sentry-webpack-plugin#options.
|
||||
}
|
||||
|
||||
module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions)
|
@ -29,6 +29,7 @@
|
||||
"@giphy/react-components": "^5.4.0",
|
||||
"@googleapis/drive": "^2.1.0",
|
||||
"@next-auth/prisma-adapter": "1.0.1",
|
||||
"@sentry/nextjs": "^6.17.7",
|
||||
"@stripe/stripe-js": "^1.22.0",
|
||||
"@udecode/plate-basic-marks": "^10.0.0",
|
||||
"@udecode/plate-common": "^7.0.2",
|
||||
@ -99,9 +100,9 @@
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"firebase-admin": "^10.0.2",
|
||||
"next-transpile-modules": "^9.0.0",
|
||||
"prettier": "^2.5.1",
|
||||
"firebase-admin": "^10.0.2",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
}
|
||||
|
65
apps/builder/pages/_error.js
Normal file
65
apps/builder/pages/_error.js
Normal file
@ -0,0 +1,65 @@
|
||||
import NextErrorComponent from 'next/error'
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => {
|
||||
if (!hasGetInitialPropsRun && err) {
|
||||
// getInitialProps is not called in case of
|
||||
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
|
||||
// err via _app.js so it can be captured
|
||||
Sentry.captureException(err)
|
||||
// Flushing is not required in this case as it only happens on the client
|
||||
}
|
||||
|
||||
return <NextErrorComponent statusCode={statusCode} />
|
||||
}
|
||||
|
||||
MyError.getInitialProps = async (context) => {
|
||||
const errorInitialProps = await NextErrorComponent.getInitialProps(context)
|
||||
|
||||
const { res, err, asPath } = context
|
||||
|
||||
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
||||
// getInitialProps has run
|
||||
errorInitialProps.hasGetInitialPropsRun = true
|
||||
|
||||
// Returning early because we don't want to log 404 errors to Sentry.
|
||||
if (res?.statusCode === 404) {
|
||||
return errorInitialProps
|
||||
}
|
||||
|
||||
// Running on the server, the response object (`res`) is available.
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
export default MyError
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { Prisma, User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
@ -28,4 +29,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -7,6 +7,7 @@ import { stringify } from 'querystring'
|
||||
import { CredentialsType } from 'models'
|
||||
import { encrypt } from 'utils'
|
||||
import { oauth2Client } from 'libs/google-sheets'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
@ -57,10 +58,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
},
|
||||
})
|
||||
const queryParams = stringify({ stepId, credentialsId })
|
||||
return res.redirect(
|
||||
res.redirect(
|
||||
`${redirectUrl}?${queryParams}` ?? `${process.env.NEXTAUTH_URL}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { oauth2Client } from 'libs/google-sheets'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
@ -15,8 +16,8 @@ const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
prompt: 'consent',
|
||||
state: Buffer.from(JSON.stringify(req.query)).toString('base64'),
|
||||
})
|
||||
return res.status(301).redirect(url)
|
||||
res.status(301).redirect(url)
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { DashboardFolder, User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
@ -34,4 +35,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { DashboardFolder } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
@ -34,4 +35,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -4,6 +4,7 @@ import { getAuthenticatedGoogleClient } from 'libs/google-sheets'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { User } from 'db'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
@ -27,4 +28,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -4,6 +4,7 @@ import { getAuthenticatedGoogleClient } from 'libs/google-sheets'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { User } from 'db'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
@ -38,4 +39,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
|
||||
@ -23,4 +24,4 @@ const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
@ -27,4 +28,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
@ -21,4 +22,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import aws from 'aws-sdk'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
@ -39,4 +40,4 @@ const handler = async (
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import Stripe from 'stripe'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const usdPriceIdTest = 'price_1Jc4TQKexUFvKTWyGvsH4Ff5'
|
||||
const createCheckoutSession = async (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) => {
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method === 'POST') {
|
||||
if (!process.env.STRIPE_SECRET_KEY)
|
||||
throw Error('STRIPE_SECRET_KEY var is missing')
|
||||
@ -32,4 +30,4 @@ const createCheckoutSession = async (
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default createCheckoutSession
|
||||
export default withSentry(handler)
|
||||
|
@ -3,11 +3,9 @@ import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import Stripe from 'stripe'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const createCheckoutSession = async (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) => {
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
if (!session?.user)
|
||||
return res.status(401).json({ message: 'Not authenticated' })
|
||||
@ -29,4 +27,4 @@ const createCheckoutSession = async (
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default createCheckoutSession
|
||||
export default withSentry(handler)
|
||||
|
@ -5,6 +5,7 @@ import Cors from 'micro-cors'
|
||||
import { buffer } from 'micro'
|
||||
import prisma from 'libs/prisma'
|
||||
import { Plan } from 'db'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
if (!process.env.STRIPE_SECRET_KEY || !process.env.STRIPE_WEBHOOK_SECRET)
|
||||
throw new Error('STRIPE_SECRET_KEY or STRIPE_WEBHOOK_SECRET missing')
|
||||
@ -70,4 +71,4 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export default cors(webhookHandler as any)
|
||||
export default withSentry(cors(webhookHandler as any))
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { Prisma, User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
@ -46,4 +47,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
@ -50,4 +51,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -5,6 +5,7 @@ import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import got, { Method, Headers, HTTPError } from 'got'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import { stringify } from 'qs'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method === 'POST') {
|
||||
@ -19,10 +20,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
stepIndex
|
||||
]
|
||||
if (!('webhook' in step))
|
||||
return {
|
||||
statusCode: 400,
|
||||
data: { message: `Couldn't find webhook` },
|
||||
}
|
||||
return res
|
||||
.status(404)
|
||||
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
||||
const result = await executeWebhook(step.webhook, variables)
|
||||
return res.status(200).send(result)
|
||||
}
|
||||
@ -101,4 +101,4 @@ const convertKeyValueTableToObject = (
|
||||
}, {})
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
@ -48,4 +49,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -4,6 +4,7 @@ import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { methodNotAllowed } from 'utils'
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getSession({ req })
|
||||
@ -38,4 +39,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { Stats } from 'models'
|
||||
@ -45,4 +46,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import prisma from 'libs/prisma'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
@ -21,4 +22,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { withSentry } from '@sentry/nextjs'
|
||||
import { Prisma, User } from 'db'
|
||||
import prisma from 'libs/prisma'
|
||||
import { Credentials } from 'models'
|
||||
@ -37,4 +38,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
export default withSentry(handler)
|
||||
|
15
apps/builder/sentry.client.config.js
Normal file
15
apps/builder/sentry.client.config.js
Normal file
@ -0,0 +1,15 @@
|
||||
// This file configures the initialization of Sentry on the browser.
|
||||
// The config you add here will be used whenever a page is visited.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 1.0,
|
||||
// ...
|
||||
// Note: if you want to override the automatic release value, do not set a
|
||||
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
||||
// that it will also get attached to your source maps
|
||||
})
|
15
apps/builder/sentry.server.config.js
Normal file
15
apps/builder/sentry.server.config.js
Normal file
@ -0,0 +1,15 @@
|
||||
// This file configures the initialization of Sentry on the browser.
|
||||
// The config you add here will be used whenever a page is visited.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
// Adjust this value in production, or use tracesSampler for greater control
|
||||
tracesSampleRate: 1.0,
|
||||
// ...
|
||||
// Note: if you want to override the automatic release value, do not set a
|
||||
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
||||
// that it will also get attached to your source maps
|
||||
})
|
Reference in New Issue
Block a user