Last active
June 11, 2020 13:02
-
-
Save rockymeza/7dec7ddb435a6851e6e27d40b1ad0c1a to your computer and use it in GitHub Desktop.
Setting up Sentry in RedwoodJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// api/src/functions/exampleFunction.js | |
import { db } from 'src/lib/db' | |
import { wrapFunction } from 'src/lib/sentry' | |
export const handler = wrapFunction(async (event, context) => { | |
return { | |
statusCode: 200, | |
body: 'Hello world', | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// web/src/components/FatalErrorBoundary/FatalErrorBoundary.js | |
import { FatalErrorBoundary as FatalErrorBoundaryBase } from '@redwoodjs/web' | |
import * as Sentry from '@sentry/browser' | |
class FatalErrorBoundary extends FatalErrorBoundaryBase { | |
componentDidCatch(error, errorInfo) { | |
Sentry.withScope((scope) => { | |
scope.setExtras(errorInfo) | |
Sentry.captureException(error) | |
}) | |
} | |
} | |
export default FatalErrorBoundary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// api/src/functions/graphql.js | |
import { | |
createGraphQLHandler, | |
makeMergedSchema, | |
makeServices, | |
} from '@redwoodjs/api' | |
import importAll from '@redwoodjs/api/importAll.macro' | |
import { db } from 'src/lib/db' | |
import { wrapFunction, wrapServices } from 'src/lib/sentry' | |
const schemas = importAll('api', 'graphql') | |
const services = importAll('api', 'services') | |
export const handler = wrapFunction( | |
createGraphQLHandler({ | |
schema: makeMergedSchema({ | |
schemas, | |
services: wrapServices(makeServices({ services })), | |
}), | |
db, | |
}) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// web/src/index.js | |
import { AuthProvider } from '@redwoodjs/auth' | |
import ReactDOM from 'react-dom' | |
import { RedwoodProvider } from '@redwoodjs/web' | |
import * as Sentry from '@sentry/browser' | |
import FatalErrorPage from 'src/pages/FatalErrorPage' | |
import FatalErrorBoundary from 'src/components/FatalErrorBoundary' | |
import Routes from 'src/Routes' | |
import './index.css' | |
if (process.env.REDWOOD_ENV_SENTRY_DSN) { | |
Sentry.init({ | |
dsn: process.env.REDWOOD_ENV_SENTRY_DSN, | |
}) | |
} | |
ReactDOM.render( | |
<FatalErrorBoundary page={FatalErrorPage}> | |
<RedwoodProvider> | |
<Routes /> | |
</RedwoodProvider> | |
</FatalErrorBoundary>, | |
document.getElementById('redwood-app') | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[build] | |
command = "yarn rw db up --no-db-client && yarn rw build" | |
publish = "web/dist" | |
functions = "api/dist/functions" | |
[dev] | |
command = "yarn rw dev" | |
[[redirects]] | |
from = "/*" | |
to = "/index.html" | |
status = 200 | |
[[plugins]] | |
package = 'netlify-plugin-prisma-provider' | |
[plugins.inputs] | |
path = 'api/prisma/schema.prisma' | |
[[plugins]] | |
package = "@sentry/netlify-build-plugin" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// api/src/lib/sentry.js | |
import * as Sentry from '@sentry/node' | |
import { context } from '@redwoodjs/api' | |
let sentryInitialized = false | |
if (process.env.REDWOOD_ENV_SENTRY_DSN && !sentryInitialized) { | |
Sentry.init({ | |
dsn: process.env.REDWOOD_ENV_SENTRY_DSN, | |
environment: process.env.CONTEXT, | |
release: process.env.COMMIT_REF, | |
}) | |
sentryInitialized = true | |
} | |
async function reportError(error) { | |
if (!sentryInitialized) return | |
if (context.currentUser) { | |
Sentry.configureScope((scope) => { | |
scope.setUser({ | |
id: context.currentUser.id, | |
email: context.currentUser.email, | |
}) | |
}) | |
} | |
if (typeof error === 'string') { | |
Sentry.captureMessage(error) | |
} else { | |
Sentry.captureException(error) | |
} | |
await Sentry.flush() | |
} | |
export const wrapFunction = (handler) => async (event, lambdaContext) => { | |
lambdaContext.callbackWaitsForEmptyEventLoop = false | |
try { | |
return await new Promise((resolve, reject) => { | |
const callback = (err, result) => { | |
if (err) reject(err) | |
resolve(result) | |
} | |
const resp = handler(event, lambdaContext, callback) | |
if (resp?.then) { | |
resp.then(resolve, reject) | |
} | |
}) | |
} catch (e) { | |
// This catches both sync errors & promise | |
// rejections, because we 'await' on the handler | |
await reportError(e) | |
throw e | |
} | |
} | |
export const wrapServiceFunction = (fn) => async (...args) => { | |
try { | |
return await fn(...args) | |
} catch (e) { | |
await reportError(e) | |
throw e | |
} | |
} | |
export const wrapService = (service) => { | |
return Object.keys(service).reduce((acc, key) => { | |
return { | |
...acc, | |
[key]: wrapServiceFunction(service[key]), | |
} | |
}, {}) | |
} | |
export const wrapServices = (services) => { | |
return Object.keys(services).reduce((acc, key) => { | |
return { | |
...acc, | |
[key]: wrapService(services[key]), | |
} | |
}, {}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment