Skip to content

H-5764: Setup Sentry UserFeedback + ErrorTracker#8241

Merged
CiaranMn merged 16 commits into
mainfrom
cf/h-5764-add-sentry-give-feedback-button-to-hosted-version-of
Jan 9, 2026
Merged

H-5764: Setup Sentry UserFeedback + ErrorTracker#8241
CiaranMn merged 16 commits into
mainfrom
cf/h-5764-add-sentry-give-feedback-button-to-hosted-version-of

Conversation

@kube
Copy link
Copy Markdown
Collaborator

@kube kube commented Jan 6, 2026

Demo

Kapture 2026-01-07 at 20.22.59.mp4 (uploaded via Graphite)

🌟 What is the purpose of this PR?

This PR adds Sentry User Feedback + Error Tracker inside Petrinaut demo website.

🔍 What does this change?

Error Tracker

Because we don't want Petrinaut to be directly coupled to Sentry:

  • Adds React Context is added ErrorTrackerContext
  • Adds ErrorTrackerContext Provider for Sentry <SentryErrorTrackerProvider> (only used in demo-website)

This SentryErrorTrackerProvider is still not used for now in the app, but will be extended later to add more granular tracking of user experience in the demo app.

User Feedback

For now the User Feedback widget is the default one, this keeps it simple and prevents having to deal with React component props, or with design.

If we get a good Figma design, we'll be able customize this feedback button to place it properly in the UI.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

Given the User Feedback widget is the default one, it's on top of the UI and could possibly hide some things.

🐾 Next steps

In the future, we'll do more granular tracking of what happens in the app.

❓ How to test this?

Use latest Petrinaut deployment

Copy link
Copy Markdown
Collaborator Author

kube commented Jan 6, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@kube kube changed the title Add @sentry/react dependency Setup Sentry UserFeedback + ErrorTracker Jan 6, 2026
@kube kube changed the title Setup Sentry UserFeedback + ErrorTracker H-5764: Setup Sentry UserFeedback + ErrorTracker Jan 7, 2026
@kube kube marked this pull request as ready for review January 7, 2026 19:25
@cursor
Copy link
Copy Markdown

cursor Bot commented Jan 7, 2026

PR Summary

Introduces Sentry-based monitoring and a generic error tracking abstraction in the demo site.

  • Initialize Sentry in sentry/instrument.ts with browser error/tracing integrations and the User Feedback widget; enable via __ENVIRONMENT__/__SENTRY_DSN__
  • Wrap app with SentryErrorTrackerProvider implementing ErrorTrackerContext; add React root onUncaughtError, onCaughtError, and onRecoverableError handlers via @sentry/react
  • Add ErrorTrackerContext interface for pluggable error tracking
  • Update vite.config.ts to loadEnv and define __ENVIRONMENT__/__SENTRY_DSN__; add vite-env.d.ts and include Sentry files in tsconfig
  • Add @sentry/react dev dependency; tweak keyboard shortcut hook to ignore #sentry-feedback

Written by Cursor Bugbot for commit 0011c00. This will update automatically on new commits. Configure here.

Comment thread libs/@hashintel/petrinaut/package.json
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented Jan 7, 2026

🤖 Augment PR Summary

Summary: This PR wires Sentry error tracking + user feedback into the Petrinaut demo site.

Changes:

  • Initialize Sentry in the demo site with browser integrations, tracing, and the default Feedback widget.
  • Add a generic ErrorTrackerContext in the Petrinaut library and a Sentry-backed provider used by the demo site.
  • Wrap the demo app with SentryErrorTrackerProvider and register React root error handlers (onUncaughtError, onCaughtError, onRecoverableError).
  • Load SENTRY_DSN from .env via Vite and expose it at build time via import.meta.env.SENTRY_DSN typings.
  • Adjust editor keyboard shortcut handling to avoid capturing keystrokes while Sentry feedback UI is focused.
  • Add @sentry/react dependency for the Petrinaut package.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

@@ -1,12 +1,30 @@
import "./sentry/instrument.js";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

./sentry/instrument.js doesn’t exist in this PR (only instrument.ts is added), so this import will likely fail at runtime/build time.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

"./*.ts",
"./*.d.ts",
"main/app.tsx",
"sentry/init-sentry.ts"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This include entry points at sentry/init-sentry.ts, but the added Sentry initializer file is sentry/instrument.ts (so this looks like a stale/incorrect path).

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

Sentry.withScope((scope) => {
if (context) {
for (const [key, value] of Object.entries(context)) {
scope.setContext(key, value as Record<string, unknown>);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scope.setContext() expects an object, but ErrorTrackerContextData allows any unknown value; passing primitives here can lead to dropped context or unexpected serialization.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

Comment thread libs/@hashintel/petrinaut/demo-site/tsconfig.json Outdated
@kube kube changed the base branch from cf/h-5691-visualiser-for-global-state to graphite-base/8241 January 8, 2026 13:07
Comment thread libs/@hashintel/petrinaut/.env Outdated
@@ -0,0 +1 @@
SENTRY_DSN=https://5c0a691258164a68eac390cd10574484@o146262.ingest.us.sentry.io/4510663776141312
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it shouldn't be committed to the repo. I've added it as an environment variable in Vercel so it will be picked up when built in Vercel.

For local testing we can add a non-committed .env.local with the value.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I remove it, environment variable is certainly better.

Comment on lines +11 to +13
typeof import.meta.env.MODE === "string"
? import.meta.env.MODE
: "development";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this 'environment' as it's what it tends to be called elsewhere.

I know that Vite sets a special 'mode' variable, but we don't actually want to rely on this – it means that if someone does a production build locally and runs it, any errors will be sent to Sentry as production errors.

The only 'production' errors in Sentry should be those from the main production site, so we need to handle setting the environment manually (via Vercel environment variables, added in a file below).

Suggested change
typeof import.meta.env.MODE === "string"
? import.meta.env.MODE
: "development";
typeof import.meta.env.ENVIRONMENT === "string"
? import.meta.env.ENVIRONMENT
: "development";

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MODE is a constant provided by Vite:

https://vite.dev/guide/env-and-mode#built-in-constants

We could provide our own but it would be repeating what is already available, or use PROD === true.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks and sorry for misreading/misunderstanding your point.


interface ImportMetaEnv {
readonly SENTRY_DSN?: string;
readonly MODE: string;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
readonly MODE: string;
readonly ENVIRONMENT: string;

const envDir = isLibMode ? undefined : path.resolve(__dirname);
const env = loadEnv(mode, envDir ?? process.cwd(), "");

// Get SENTRY_DSN from environment variables
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Get SENTRY_DSN from environment variables

const isLibMode = mode === "lib" || !!process.env.VITEST;

// Load environment variables from .env files
// For demo-site builds, load from the package root directory
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// For demo-site builds, load from the package root directory

const env = loadEnv(mode, envDir ?? process.cwd(), "");

// Get SENTRY_DSN from environment variables
const sentryDsn = env.SENTRY_DSN ?? process.env.SENTRY_DSN;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Load the environment from Vercel (which will be either production for the main site or preview for preview builds)

See https://vercel.com/docs/frameworks/frontend/vite#environment-variables

Suggested change
const sentryDsn = env.SENTRY_DSN ?? process.env.SENTRY_DSN;
const sentryDsn = env.SENTRY_DSN ?? process.env.SENTRY_DSN;
const environment = process.env.VITE_VERCEL_ENV ?? "development";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line only makes sense for the demo site build so maybe we should only inject it in there somehow?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave it in here for now

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define in the config works by text replacement (if I'm not mistaken)

So this won't be bundled in the library, because there won't be no reference to the global variable in the library.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna use define for that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CiaranMn I updated to use define, with __SENTRY_DSN__ and __ENVIRONMENT__

// Provide minimal process shim for TypeScript language service in browser
"process.versions": JSON.stringify({ pnp: undefined }),
// Expose SENTRY_DSN at build time
"import.meta.env.SENTRY_DSN": JSON.stringify(sentryDsn),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"import.meta.env.SENTRY_DSN": JSON.stringify(sentryDsn),
"import.meta.env.SENTRY_DSN": JSON.stringify(sentryDsn),
"import.meta.env.ENVIRONMENT": environment,

@kube kube force-pushed the cf/h-5764-add-sentry-give-feedback-button-to-hosted-version-of branch from 7a07628 to c0d3e32 Compare January 9, 2026 09:45
@kube kube force-pushed the graphite-base/8241 branch from f04e2f5 to 5b67a3b Compare January 9, 2026 09:45
@kube kube changed the base branch from graphite-base/8241 to main January 9, 2026 09:45
@github-actions github-actions Bot removed the area/infra Relates to version control, CI, CD or IaC (area) label Jan 9, 2026
@graphite-app graphite-app Bot requested a review from a team January 9, 2026 09:45
Comment thread libs/@hashintel/petrinaut/vite.config.ts Outdated
…e: replace direct access to SENTRY_DSN with build-time injected constants, and streamline Sentry initialization to use these constants.
@CiaranMn CiaranMn added this pull request to the merge queue Jan 9, 2026
Merged via the queue into main with commit f9a1894 Jan 9, 2026
40 checks passed
@CiaranMn CiaranMn deleted the cf/h-5764-add-sentry-give-feedback-button-to-hosted-version-of branch January 9, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deps Relates to third-party dependencies (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants