laravel.tsx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import {Alert} from 'sentry/components/core/alert';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  4. import type {
  5. Docs,
  6. DocsParams,
  7. OnboardingConfig,
  8. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  9. import {
  10. getCrashReportModalConfigDescription,
  11. getCrashReportModalIntroduction,
  12. getCrashReportSDKInstallFirstStep,
  13. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  14. import {
  15. feedbackOnboardingJsLoader,
  16. replayOnboardingJsLoader,
  17. } from 'sentry/gettingStartedDocs/javascript/jsLoader/jsLoader';
  18. import {t, tct} from 'sentry/locale';
  19. type Params = DocsParams;
  20. const getExceptionHandlerSnippet = () => `
  21. <?php
  22. use Illuminate\\Foundation\\Application;
  23. use Illuminate\\Foundation\\Configuration\\Exceptions;
  24. use Illuminate\\Foundation\\Configuration\\Middleware;
  25. use Sentry\\Laravel\\Integration;
  26. return Application::configure(basePath: dirname(__DIR__))
  27. ->withRouting(
  28. web: __DIR__.'/../routes/web.php',
  29. commands: __DIR__.'/../routes/console.php',
  30. health: '/up',
  31. )
  32. ->withMiddleware(function (Middleware $middleware) {
  33. //
  34. })
  35. ->withExceptions(function (Exceptions $exceptions) {
  36. Integration::handles($exceptions);
  37. })->create();`;
  38. const getConfigureSnippet = (params: Params) =>
  39. `SENTRY_LARAVEL_DSN=${params.dsn.public}${
  40. params.isPerformanceSelected
  41. ? `
  42. # Specify a fixed sample rate
  43. SENTRY_TRACES_SAMPLE_RATE=1.0`
  44. : ''
  45. }${
  46. params.isProfilingSelected
  47. ? `
  48. # Set a sampling rate for profiling - this is relative to traces_sample_rate
  49. SENTRY_PROFILES_SAMPLE_RATE=1.0`
  50. : ''
  51. }`;
  52. const onboarding: OnboardingConfig = {
  53. introduction: () => (
  54. <p>
  55. {tct(
  56. 'This guide is for Laravel 11.0 an up. We also provide instructions for [otherVersionsLink:other versions] as well as [lumenSpecificLink:Lumen-specific instructions].',
  57. {
  58. otherVersionsLink: (
  59. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/other-versions/" />
  60. ),
  61. lumenSpecificLink: (
  62. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/other-versions/lumen/" />
  63. ),
  64. }
  65. )}
  66. </p>
  67. ),
  68. install: (params: Params) => [
  69. {
  70. type: StepType.INSTALL,
  71. configurations: [
  72. {
  73. description: tct('Install the [code:sentry/sentry-laravel] package:', {
  74. code: <code />,
  75. }),
  76. language: 'bash',
  77. code: `composer require sentry/sentry-laravel`,
  78. },
  79. ...(params.isProfilingSelected
  80. ? [
  81. {
  82. description: t('Install the Excimer extension via PECL:'),
  83. language: 'bash',
  84. code: 'pecl install excimer',
  85. },
  86. {
  87. description: tct(
  88. "The Excimer PHP extension supports PHP 7.2 and up. Excimer requires Linux or macOS and doesn't support Windows. For additional ways to install Excimer, see [sentryPhpDocumentationLink: Sentry documentation].",
  89. {
  90. sentryPhpDocumentationLink: (
  91. <ExternalLink href="https://docs.sentry.io/platforms/php/profiling/#installation" />
  92. ),
  93. }
  94. ),
  95. },
  96. ]
  97. : []),
  98. {
  99. description: tct(
  100. 'Enable capturing unhandled exception to report to Sentry by making the following change to your [code:bootstrap/app.php]:',
  101. {
  102. code: <code />,
  103. }
  104. ),
  105. language: 'php',
  106. code: getExceptionHandlerSnippet(),
  107. },
  108. ],
  109. },
  110. ],
  111. configure: (params: Params) => [
  112. {
  113. type: StepType.CONFIGURE,
  114. configurations: [
  115. {
  116. description: t('Configure the Sentry DSN with this command:'),
  117. language: 'shell',
  118. code: `php artisan sentry:publish --dsn=${params.dsn.public}`,
  119. },
  120. {
  121. description: tct(
  122. 'It creates the config file ([code:config/sentry.php]) and adds the [code:DSN] to your [code:.env] file where you can add further configuration options:',
  123. {code: <code />}
  124. ),
  125. language: 'shell',
  126. code: getConfigureSnippet(params),
  127. },
  128. {
  129. description: (
  130. <Alert.Container>
  131. <Alert type="warning">
  132. {tct(
  133. 'In order to receive stack trace arguments in your errors, make sure to set [code:zend.exception_ignore_args: Off] in your php.ini',
  134. {
  135. code: <code />,
  136. }
  137. )}
  138. </Alert>
  139. </Alert.Container>
  140. ),
  141. },
  142. ],
  143. },
  144. ],
  145. verify: () => [
  146. {
  147. type: StepType.VERIFY,
  148. configurations: [
  149. {
  150. description: tct(
  151. 'You can test your configuration using the provided [code:sentry:test] artisan command:',
  152. {
  153. code: <code />,
  154. }
  155. ),
  156. language: 'shell',
  157. code: 'php artisan sentry:test',
  158. },
  159. ],
  160. },
  161. ],
  162. nextSteps: () => [],
  163. };
  164. const crashReportOnboarding: OnboardingConfig = {
  165. introduction: () => getCrashReportModalIntroduction(),
  166. install: (params: Params) => [
  167. {
  168. type: StepType.INSTALL,
  169. configurations: [
  170. getCrashReportSDKInstallFirstStep(params),
  171. {
  172. description: tct(
  173. 'Next, create [code:resources/views/errors/500.blade.php], and embed the feedback code:',
  174. {code: <code />}
  175. ),
  176. code: [
  177. {
  178. label: 'HTML',
  179. value: 'html',
  180. language: 'html',
  181. code: `<div class="content">
  182. <div class="title">Something went wrong.</div>
  183. @if(app()->bound('sentry') && app('sentry')->getLastEventId())
  184. <div class="subtitle">Error ID: {{ app('sentry')->getLastEventId() }}</div>
  185. <script>
  186. Sentry.init({ dsn: '${params.dsn.public}' });
  187. Sentry.showReportDialog({
  188. eventId: '{{ app('sentry')->getLastEventId() }}'
  189. });
  190. </script>
  191. @endif
  192. </div>`,
  193. },
  194. ],
  195. },
  196. {
  197. description: tct(
  198. 'For Laravel 5 up to 5.4 there is some extra work needed. You need to open up [codeApp:App/Exceptions/Handler.php] and extend the [codeRender:render] method to make sure the 500 error is rendered as a view correctly, in 5.5+ this step is not required anymore.',
  199. {code: <code />}
  200. ),
  201. code: [
  202. {
  203. label: 'PHP',
  204. value: 'php',
  205. language: 'php',
  206. code: `<?php
  207. use Symfony\Component\HttpKernel\Exception\HttpException;
  208. class Handler extends ExceptionHandler
  209. {
  210. public function report(Exception $exception)
  211. {
  212. if (app()->bound('sentry') && $this->shouldReport($exception)) {
  213. app('sentry')->captureException($exception);
  214. }
  215. parent::report($exception);
  216. }
  217. // This method is ONLY needed for Laravel 5 up to 5.4.
  218. // You can skip this method if you are using Laravel 5.5+.
  219. public function render($request, Exception $exception)
  220. {
  221. // Convert all non-http exceptions to a proper 500 http exception
  222. // if we don't do this exceptions are shown as a default template
  223. // instead of our own view in resources/views/errors/500.blade.php
  224. if ($this->shouldReport($exception) && !$this->isHttpException($exception) && !config('app.debug')) {
  225. $exception = new HttpException(500, 'Whoops!');
  226. }
  227. return parent::render($request, $exception);
  228. }
  229. }`,
  230. },
  231. ],
  232. },
  233. ],
  234. },
  235. ],
  236. configure: () => [
  237. {
  238. type: StepType.CONFIGURE,
  239. description: getCrashReportModalConfigDescription({
  240. link: 'https://docs.sentry.io/platforms/php/guides/laravel/user-feedback/configuration/#crash-report-modal',
  241. }),
  242. },
  243. ],
  244. verify: () => [],
  245. nextSteps: () => [],
  246. };
  247. const docs: Docs = {
  248. onboarding,
  249. replayOnboardingJsLoader,
  250. crashReportOnboarding,
  251. feedbackOnboardingJsLoader,
  252. };
  253. export default docs;