Skip to content

Commit

Permalink
frontend: Bugsnag setup (#2766)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdslaugh authored Aug 21, 2023
1 parent d444f9a commit 3719e34
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 2 deletions.
31 changes: 31 additions & 0 deletions docs/development/frontend/bugsnag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: BugSnag
{{ .EditURL }}
---

The frontend code in Clutch allows a user to utilize BugSnag for their bug catching abilities. The setup when using a Gateway or the normal clutch app is quite simple as it just requires the usage of environment variables.

An example is below

## Structure
```
frontend
├─ package.json
├─ .env.production
├─ ...
```

### Example Script in package.json
```json
"upload-sourcemaps": "yarn workspace @clutch-sh/tools uploadSourcemaps $PWD build/static .env.production --"
```

### Example .env.production
```bash
REACT_APP_SERVICE_NAME=<app>
REACT_APP_BUGSNAG_API_TOKEN=....
REACT_APP_BASE_URL=https://<app>.net
APPLICATION_ENV=production
```

And thats it, after setting up these few items Clutch will wrap the application in a BugSnag error boundary and report errors as it catches them.
1 change: 1 addition & 0 deletions docs/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"items": [
"development/frontend/overview",
"development/frontend/storybook",
"development/frontend/bugsnag",
{
"type": "link",
"label": "Clutch's Storybook",
Expand Down
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"last 1 safari version"
]
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.16.0",
"@mui/material": "^5.8.5",
Expand Down
2 changes: 2 additions & 0 deletions frontend/packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"@mui/base": "5.0.0-alpha.86"
},
"dependencies": {
"@bugsnag/js": "^7.21.0",
"@bugsnag/plugin-react": "^7.19.0",
"@clutch-sh/api": "^2.0.0-beta",
"@date-io/core": "^1.3.6",
"@emotion/jest": "^11.0.0",
Expand Down
25 changes: 24 additions & 1 deletion frontend/packages/core/src/AppProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from "react";
import { BrowserRouter as Router, Outlet, Route, Routes } from "react-router-dom";
import Bugsnag from "@bugsnag/js";
import BugsnagPluginReact from "@bugsnag/plugin-react";

import AppLayout from "../AppLayout";
import { ApplicationContext, ShortLinkContext } from "../Contexts";
Expand Down Expand Up @@ -205,4 +207,25 @@ const ClutchApp: React.FC<ClutchAppProps> = ({
);
};

export default ClutchApp;
const BugSnagApp = props => {
if (process.env.REACT_APP_BUGSNAG_API_TOKEN) {
// eslint-disable-next-line no-underscore-dangle
if (!(Bugsnag as any)._client) {
Bugsnag.start({
apiKey: process.env.REACT_APP_BUGSNAG_API_TOKEN,
plugins: [new BugsnagPluginReact()],
releaseStage: process.env.APPLICATION_ENV || "production",
});
}
const BugsnagBoundary = Bugsnag.getPlugin("react").createErrorBoundary(React);
return (
<BugsnagBoundary>
<ClutchApp {...props} />
</BugsnagBoundary>
);
}

return <ClutchApp {...props} />;
};

export default BugSnagApp;
5 changes: 4 additions & 1 deletion frontend/packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "yarn run lint --fix",
"publishBeta": "../../../tools/publish-frontend.sh tools",
"registerWorkflows": "node workflow-registrar.js"
"registerWorkflows": "node workflow-registrar.js",
"uploadSourcemaps": "node upload-sourcemaps.js"
},
"dependencies": {
"@babel/cli": "^7.7.5",
Expand All @@ -22,6 +23,7 @@
"@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
"@babel/preset-typescript": "^7.16.0",
"@bugsnag/source-maps": "^2.3.1",
"@types/enzyme": "^3.10.8",
"@types/jest": "^29.0.0",
"@types/mocha": "^10.0.0",
Expand All @@ -34,6 +36,7 @@
"babel-jest": "^27.4.2",
"babel-plugin-module-resolver": "^4.0.0",
"cypress": "9.7.0",
"dotenv": "^16.3.1",
"enzyme": "^3.11.0",
"esbuild": "^0.18.0",
"eslint": "^8.3.0",
Expand Down
49 changes: 49 additions & 0 deletions frontend/packages/tools/upload-sourcemaps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-disable no-console */
const { browser } = require("@bugsnag/source-maps");
const { config } = require("dotenv");

const srcDir = process.argv[2];
const buildDir = process.argv[3];
const envFile = process.argv[4];

const dotEnvFile = `${srcDir}/${envFile}`;

config({ path: dotEnvFile });

const uploadToBugsnag = async ({ apiKey, baseUrl, distDir: directory }) => {
try {
await browser.uploadMultiple({
apiKey,
baseUrl,
directory,
overwrite: true,
});
console.info(`[BugSnag] Successfully uploaded source maps ${directory} to BugSnag`);
} catch (err) {
console.error(`[BugSnag] Error uploading source maps to BugSnag: ${err}`);
}
};

const uploadBugsnagSourcemaps = () => {
const apiKey = process.env.REACT_APP_BUGSNAG_API_TOKEN || "";
const baseUrl = process.env.REACT_APP_BASE_URL || "";
if (!apiKey) {
console.error(`[BugSnag] No API token found in ${dotEnvFile} file. Skipping upload.`);
return Promise.reject(new Error("[BugSnag] API Key missing"));
}

if (!baseUrl) {
console.error(
`[BugSnag] No BaseUrl defined in process.env.BASE_URL in ${dotEnvFile}. Skipping Upload`
);
return Promise.reject(new Error("[BugSnag] BaseUrl missing"));
}

return uploadToBugsnag({
apiKey,
baseUrl: `${baseUrl}${process.env.REACT_APP_BASE_URL_PATH ?? "/static/js/"}`,
distDir: process.env.SOURCEMAPS_DIR || `${srcDir}/${buildDir}`,
});
};

uploadBugsnagSourcemaps();
Loading

0 comments on commit 3719e34

Please sign in to comment.