express.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
  2. import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
  3. import {StepProps, StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  4. import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils';
  5. import {t, tct} from 'sentry/locale';
  6. import {
  7. getDefaultInitParams,
  8. getDefaultNodeImports,
  9. getInstallSnippet,
  10. getProductInitParams,
  11. getProductIntegrations,
  12. getProductSelectionMap,
  13. joinWithIndentation,
  14. } from 'sentry/utils/gettingStartedDocs/node';
  15. interface StepsParams {
  16. hasPerformanceMonitoring: boolean;
  17. importContent: string;
  18. initContent: string;
  19. installSnippet: string;
  20. sourceMapStep: StepProps;
  21. }
  22. const performanceIntegrations: string[] = [
  23. '// enable HTTP calls tracing',
  24. 'new Sentry.Integrations.Http({ tracing: true }),',
  25. '// enable Express.js middleware tracing',
  26. 'new Sentry.Integrations.Express({ app }),',
  27. ];
  28. export const steps = ({
  29. installSnippet,
  30. importContent,
  31. initContent,
  32. hasPerformanceMonitoring,
  33. sourceMapStep,
  34. }: StepsParams): LayoutProps['steps'] => [
  35. {
  36. type: StepType.INSTALL,
  37. description: t('Add the Sentry Node SDK as a dependency:'),
  38. configurations: [
  39. {
  40. language: 'bash',
  41. code: installSnippet,
  42. },
  43. ],
  44. },
  45. {
  46. type: StepType.CONFIGURE,
  47. description: (
  48. <p>
  49. {tct(
  50. "Initialize Sentry as early as possible in your application's lifecycle, for example in your [code:index.ts/js] entry point:",
  51. {code: <code />}
  52. )}
  53. </p>
  54. ),
  55. configurations: [
  56. {
  57. language: 'javascript',
  58. code: `
  59. ${importContent}
  60. const app = express();
  61. Sentry.init({
  62. ${initContent}
  63. });
  64. // The request handler must be the first middleware on the app
  65. app.use(Sentry.Handlers.requestHandler());${
  66. hasPerformanceMonitoring
  67. ? `
  68. // TracingHandler creates a trace for every incoming request
  69. app.use(Sentry.Handlers.tracingHandler());`
  70. : ''
  71. }
  72. // All your controllers should live here
  73. app.get("/", function rootHandler(req, res) {
  74. res.end("Hello world!");
  75. });
  76. // The error handler must be registered before any other error middleware and after all controllers
  77. app.use(Sentry.Handlers.errorHandler());
  78. // Optional fallthrough error handler
  79. app.use(function onError(err, req, res, next) {
  80. // The error id is attached to \`res.sentry\` to be returned
  81. // and optionally displayed to the user for support.
  82. res.statusCode = 500;
  83. res.end(res.sentry + "\\n");
  84. });
  85. app.listen(3000);
  86. `,
  87. },
  88. ],
  89. },
  90. sourceMapStep,
  91. {
  92. type: StepType.VERIFY,
  93. description: t(
  94. "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected."
  95. ),
  96. configurations: [
  97. {
  98. language: 'javascript',
  99. code: `
  100. app.get("/debug-sentry", function mainHandler(req, res) {
  101. throw new Error("My first Sentry error!");
  102. });
  103. `,
  104. },
  105. ],
  106. },
  107. ];
  108. export function GettingStartedWithExpress({
  109. dsn,
  110. newOrg,
  111. platformKey,
  112. activeProductSelection = [],
  113. organization,
  114. projectId,
  115. ...props
  116. }: ModuleProps) {
  117. const productSelection = getProductSelectionMap(activeProductSelection);
  118. const installSnippet = getInstallSnippet({productSelection});
  119. const imports = getDefaultNodeImports({productSelection});
  120. imports.push('import express from "express";');
  121. const integrations = [
  122. ...(productSelection['performance-monitoring'] ? performanceIntegrations : []),
  123. ...getProductIntegrations({productSelection}),
  124. ];
  125. const integrationParam =
  126. integrations.length > 0
  127. ? `integrations: [\n${joinWithIndentation(integrations)}\n],`
  128. : null;
  129. const initContent = joinWithIndentation([
  130. ...getDefaultInitParams({dsn}),
  131. ...(integrationParam ? [integrationParam] : []),
  132. ...getProductInitParams({productSelection}),
  133. ]);
  134. return (
  135. <Layout
  136. steps={steps({
  137. installSnippet,
  138. importContent: imports.join('\n'),
  139. initContent,
  140. hasPerformanceMonitoring: productSelection['performance-monitoring'],
  141. sourceMapStep: getUploadSourceMapsStep({
  142. guideLink: 'https://docs.sentry.io/platforms/node/guides/express/sourcemaps/',
  143. organization,
  144. platformKey,
  145. projectId,
  146. newOrg,
  147. }),
  148. })}
  149. newOrg={newOrg}
  150. platformKey={platformKey}
  151. {...props}
  152. />
  153. );
  154. }
  155. export default GettingStartedWithExpress;