Skip to content

Commit

Permalink
build: 🏗️ Add Sentry to builder
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Feb 14, 2022
1 parent 5a060c7 commit 8501d39
Show file tree
Hide file tree
Showing 31 changed files with 474 additions and 52 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ playwright-report
dist
test-results
**/api/scripts
.sentryclirc
sentry.properties
3 changes: 3 additions & 0 deletions apps/builder/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
14 changes: 14 additions & 0 deletions apps/builder/next.config.js
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 2 additions & 1 deletion apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 changes: 65 additions & 0 deletions apps/builder/pages/_error.js
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion apps/builder/pages/api/coupons/redeem.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { Prisma, User } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
Expand Down Expand Up @@ -28,4 +29,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}
}

export default handler
export default withSentry(handler)
5 changes: 3 additions & 2 deletions apps/builder/pages/api/credentials/google-sheets/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand Down Expand Up @@ -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)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { oauth2Client } from 'libs/google-sheets'
import { NextApiRequest, NextApiResponse } from 'next'

Expand All @@ -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)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/folders.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { DashboardFolder, User } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
Expand Down Expand Up @@ -34,4 +35,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/folders/[id].ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { DashboardFolder } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
Expand Down Expand Up @@ -34,4 +35,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand All @@ -27,4 +28,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand Down Expand Up @@ -38,4 +39,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/mock/webhook.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { NextApiRequest, NextApiResponse } from 'next'
import { methodNotAllowed } from 'utils'

Expand All @@ -23,4 +24,4 @@ const handler = (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/publicTypebots.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -27,4 +28,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/publicTypebots/[id].ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -21,4 +22,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/storage/upload-url.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -39,4 +40,4 @@ const handler = async (
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
8 changes: 3 additions & 5 deletions apps/builder/pages/api/stripe/checkout.ts
Original file line number Diff line number Diff line change
@@ -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')
Expand All @@ -32,4 +30,4 @@ const createCheckoutSession = async (
return methodNotAllowed(res)
}

export default createCheckoutSession
export default withSentry(handler)
8 changes: 3 additions & 5 deletions apps/builder/pages/api/stripe/customer-portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
Expand All @@ -29,4 +27,4 @@ const createCheckoutSession = async (
return methodNotAllowed(res)
}

export default createCheckoutSession
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/stripe/webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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))
3 changes: 2 additions & 1 deletion apps/builder/pages/api/typebots.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { Prisma, User } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
Expand Down Expand Up @@ -46,4 +47,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/typebots/[typebotId].ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -50,4 +51,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand All @@ -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)
}
Expand Down Expand Up @@ -101,4 +101,4 @@ const convertKeyValueTableToObject = (
}, {})
}

export default handler
export default withSentry(handler)
3 changes: 2 additions & 1 deletion apps/builder/pages/api/typebots/[typebotId]/results.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSentry } from '@sentry/nextjs'
import { User } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
Expand Down Expand Up @@ -48,4 +49,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand Down Expand Up @@ -38,4 +39,4 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return methodNotAllowed(res)
}

export default handler
export default withSentry(handler)
Loading

2 comments on commit 8501d39

@vercel
Copy link

@vercel vercel bot commented on 8501d39 Feb 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

typebot-viewer.vercel.app
viewer-v2-typebot-io.vercel.app
viewer-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 8501d39 Feb 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

landing-page-v2 – ./apps/landing-page

landing-page-v2-typebot-io.vercel.app
landing-page-v2-jade.vercel.app
landing-page-v2-git-main-typebot-io.vercel.app

Please sign in to comment.