import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout'; import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation'; import {StepProps, StepType} from 'sentry/components/onboarding/gettingStartedDoc/step'; import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils'; import {t, tct} from 'sentry/locale'; import { getDefaultInitParams, getDefaultNodeImports, getInstallSnippet, getProductInitParams, getProductIntegrations, getProductSelectionMap, joinWithIndentation, } from 'sentry/utils/gettingStartedDocs/node'; interface StepsParams { hasPerformanceMonitoring: boolean; importContent: string; initContent: string; installSnippetNpm: string; installSnippetYarn: string; sourceMapStep: StepProps; } const performanceIntegrations: string[] = [ '// enable HTTP calls tracing', 'new Sentry.Integrations.Http({ tracing: true }),', '// enable Express.js middleware tracing', 'new Sentry.Integrations.Express({ app }),', ]; export const steps = ({ installSnippetYarn, installSnippetNpm, importContent, initContent, hasPerformanceMonitoring, sourceMapStep, }: StepsParams): LayoutProps['steps'] => [ { type: StepType.INSTALL, description: t('Add the Sentry Node SDK as a dependency:'), configurations: [ { code: [ { label: 'npm', value: 'npm', language: 'bash', code: installSnippetNpm, }, { label: 'yarn', value: 'yarn', language: 'bash', code: installSnippetYarn, }, ], }, ], }, { type: StepType.CONFIGURE, description: (

{tct( "Initialize Sentry as early as possible in your application's lifecycle, for example in your [code:index.ts/js] entry point:", {code: } )}

), configurations: [ { language: 'javascript', code: ` ${importContent} const app = express(); Sentry.init({ ${initContent} }); // The request handler must be the first middleware on the app app.use(Sentry.Handlers.requestHandler());${ hasPerformanceMonitoring ? ` // TracingHandler creates a trace for every incoming request app.use(Sentry.Handlers.tracingHandler());` : '' } // All your controllers should live here app.get("/", function rootHandler(req, res) { res.end("Hello world!"); }); // The error handler must be registered before any other error middleware and after all controllers app.use(Sentry.Handlers.errorHandler()); // Optional fallthrough error handler app.use(function onError(err, req, res, next) { // The error id is attached to \`res.sentry\` to be returned // and optionally displayed to the user for support. res.statusCode = 500; res.end(res.sentry + "\\n"); }); app.listen(3000); `, }, ], }, sourceMapStep, { type: StepType.VERIFY, description: t( "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected." ), configurations: [ { language: 'javascript', code: ` app.get("/debug-sentry", function mainHandler(req, res) { throw new Error("My first Sentry error!"); }); `, }, ], }, ]; export function GettingStartedWithExpress({ dsn, newOrg, platformKey, activeProductSelection = [], organization, projectId, ...props }: ModuleProps) { const productSelection = getProductSelectionMap(activeProductSelection); const imports = getDefaultNodeImports({productSelection}); imports.push('import express from "express";'); const integrations = [ ...(productSelection['performance-monitoring'] ? performanceIntegrations : []), ...getProductIntegrations({productSelection}), ]; const integrationParam = integrations.length > 0 ? `integrations: [\n${joinWithIndentation(integrations)}\n],` : null; const initContent = joinWithIndentation([ ...getDefaultInitParams({dsn}), ...(integrationParam ? [integrationParam] : []), ...getProductInitParams({productSelection}), ]); return ( ); } export default GettingStartedWithExpress;