-
Notifications
You must be signed in to change notification settings - Fork 6
Feat: add sentry to web-app #1472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e2e1585
8f4f619
b4acc61
cc7a01d
94c4a4c
e317124
535ed6d
12103ce
3375e59
cd32c40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,6 +38,10 @@ on: | |
| description: 1Password GitHub token secret reference | ||
| type: string | ||
| required: false | ||
| OP_SENTRY_DSN: | ||
| description: Reference to the 1Password Sentry DSN secret | ||
| type: string | ||
| required: false | ||
| ENABLE_QUALITY_CHECKS: | ||
| description: When true the tests and lint checks are performed(default), false will skip. This is only valid in protopype and demo deployments | ||
| type: boolean | ||
|
|
@@ -172,6 +176,7 @@ jobs: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | ||
| SLACK_WEBHOOK_URL: ${{inputs.OP_SLACK_WEBHOOK_URL}} | ||
| ADD_FEED_FORM_GITHUB_TOKEN: ${{inputs.OP_ADD_FEED_FORM_GITHUB_TOKEN}} | ||
| SENTRY_DSN: ${{inputs.OP_SENTRY_DSN}} | ||
|
|
||
| - name: Authenticate to Google Cloud DEV | ||
| if: ${{ inputs.FIREBASE_PROJECT == 'dev' }} | ||
|
|
@@ -235,6 +240,10 @@ jobs: | |
| echo "REACT_APP_REMOTE_CONFIG_MINIMUM_FETCH_INTERVAL_MILLI=3600000" >> $GITHUB_ENV | ||
| echo "REACT_APP_FEED_API_BASE_URL=https://api.mobilitydatabase.org" >> $GITHUB_ENV | ||
| echo "REACT_APP_GBFS_VALIDATOR_API_BASE_URL=https://dev.gbfs.api.mobilitydatabase.org" >> $GITHUB_ENV | ||
| echo "REACT_APP_SENTRY_DSN=${{ env.SENTRY_DSN }}" >> $GITHUB_ENV | ||
| echo "REACT_APP_SENTRY_REPLAY_SESSION_SAMPLE_RATE=0.1" >> $GITHUB_ENV | ||
| echo "REACT_APP_SENTRY_REPLAY_ERROR_SAMPLE_RATE=0.1" >> $GITHUB_ENV | ||
| echo "REACT_APP_SENTRY_TRACES_SAMPLE_RATE=0.05" >> $GITHUB_ENV | ||
|
Comment on lines
+243
to
+246
|
||
| else | ||
| echo "Setting FIREBASE_PROJECT to 'dev'" | ||
| echo "FIREBASE_PROJECT=dev" >> $GITHUB_ENV | ||
|
|
@@ -253,7 +262,7 @@ jobs: | |
| - name: Populate Variables | ||
| working-directory: web-app | ||
| run: | | ||
| ../scripts/replace-variables.sh -in_file src/.env.rename_me -out_file src/.env.${{ inputs.FIREBASE_PROJECT }} -variables REACT_APP_FIREBASE_API_KEY,REACT_APP_FIREBASE_AUTH_DOMAIN,REACT_APP_FIREBASE_PROJECT_ID,REACT_APP_FIREBASE_STORAGE_BUCKET,REACT_APP_FIREBASE_MESSAGING_SENDER_ID,REACT_APP_FIREBASE_APP_ID,REACT_APP_RECAPTCHA_SITE_KEY,REACT_APP_GOOGLE_ANALYTICS_ID,REACT_APP_REMOTE_CONFIG_MINIMUM_FETCH_INTERVAL_MILLI,REACT_APP_FEED_API_BASE_URL,REACT_APP_GBFS_VALIDATOR_API_BASE_URL | ||
| ../scripts/replace-variables.sh -in_file src/.env.rename_me -out_file src/.env.${{ inputs.FIREBASE_PROJECT }} -variables REACT_APP_FIREBASE_API_KEY,REACT_APP_FIREBASE_AUTH_DOMAIN,REACT_APP_FIREBASE_PROJECT_ID,REACT_APP_FIREBASE_STORAGE_BUCKET,REACT_APP_FIREBASE_MESSAGING_SENDER_ID,REACT_APP_FIREBASE_APP_ID,REACT_APP_RECAPTCHA_SITE_KEY,REACT_APP_GOOGLE_ANALYTICS_ID,REACT_APP_REMOTE_CONFIG_MINIMUM_FETCH_INTERVAL_MILLI,REACT_APP_FEED_API_BASE_URL,REACT_APP_GBFS_VALIDATOR_API_BASE_URL -optional_variables REACT_APP_SENTRY_DSN,REACT_APP_SENTRY_TRACES_SAMPLE_RATE,REACT_APP_SENTRY_REPLAY_SESSION_SAMPLE_RATE,REACT_APP_SENTRY_REPLAY_ERROR_SAMPLE_RATE | ||
|
|
||
| - name: Run Install for Functions | ||
| if: ${{ inputs.DEPLOY_FIREBASE_FUNCTIONS }} | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this script was modified to accept |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| import React, { useState } from 'react'; | ||
| import { | ||
| Box, | ||
| Button, | ||
| Collapse, | ||
| Typography, | ||
| Stack, | ||
| Card, | ||
| CardContent, | ||
| Alert, | ||
| } from '@mui/material'; | ||
|
|
||
| export interface SentryErrorFallbackProps { | ||
| error: unknown; | ||
| eventId?: string; | ||
| resetError?: () => void; | ||
| } | ||
|
|
||
| const formatError = (error: unknown): string => { | ||
| if (error instanceof Error) { | ||
| return `${error.message}\n${error.stack}`; | ||
| } | ||
| try { | ||
| return typeof error === 'string' ? error : JSON.stringify(error, null, 2); | ||
| } catch { | ||
| return String(error); | ||
| } | ||
| }; | ||
|
Comment on lines
+19
to
+28
|
||
|
|
||
| export const SentryErrorFallback: React.FC<SentryErrorFallbackProps> = ({ | ||
| error, | ||
| eventId, | ||
| resetError, | ||
| }) => { | ||
| const [showDetails, setShowDetails] = useState(false); | ||
| const details = formatError(error); | ||
| return ( | ||
| <Box sx={{ p: 4, maxWidth: 760, m: '40px auto' }}> | ||
| <Card variant='outlined'> | ||
| <CardContent> | ||
| <Stack spacing={2}> | ||
| <Alert severity='error' variant='outlined'> | ||
| <Typography | ||
| variant='h5' | ||
| component='h2' | ||
| sx={{ mb: 1, fontWeight: 600 }} | ||
| > | ||
| Something went wrong | ||
| </Typography> | ||
| <Typography variant='body2'> | ||
| Our team has been notified. You can try reloading or attempt to | ||
| recover. | ||
| </Typography> | ||
| </Alert> | ||
| {eventId != null && ( | ||
| <Typography variant='caption' color='text.secondary'> | ||
| Event ID: {eventId} | ||
| </Typography> | ||
| )} | ||
| <Stack direction='row' spacing={1}> | ||
| <Button | ||
| variant='contained' | ||
| color='error' | ||
| onClick={() => { | ||
| window.location.reload(); | ||
| }} | ||
| > | ||
| Reload Page | ||
| </Button> | ||
| {resetError != null && ( | ||
| <Button variant='outlined' color='primary' onClick={resetError}> | ||
| Try Again | ||
| </Button> | ||
| )} | ||
| <Button | ||
| variant='text' | ||
| color='inherit' | ||
| onClick={() => { | ||
| setShowDetails((v) => !v); | ||
| }} | ||
| > | ||
| {showDetails ? 'Hide Details' : 'Show Details'} | ||
| </Button> | ||
| </Stack> | ||
| <Collapse in={showDetails} unmountOnExit> | ||
| <Box | ||
| sx={{ | ||
| mt: 1, | ||
| p: 2, | ||
| bgcolor: 'background.default', | ||
| borderRadius: 1, | ||
| fontFamily: 'monospace', | ||
| fontSize: 12, | ||
| whiteSpace: 'pre-wrap', | ||
| wordBreak: 'break-word', | ||
| maxHeight: 300, | ||
| overflow: 'auto', | ||
| border: '1px solid', | ||
| borderColor: 'divider', | ||
| }} | ||
| > | ||
| {details} | ||
| </Box> | ||
| </Collapse> | ||
| </Stack> | ||
| </CardContent> | ||
| </Card> | ||
| </Box> | ||
| ); | ||
| }; | ||
|
|
||
| export default SentryErrorFallback; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The
OP_SENTRY_DSNinput parameter is marked asrequired: false, but in production it's expected to be provided. Consider making this required or adding validation in the workflow to ensure it's provided for production deployments. Without the DSN, Sentry won't function, which could lead to silent failures in error tracking.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is fine due to the qa and dev environment not requiring it