Skip to content

Commit 8ae738e

Browse files
sarahxsandersPostHoggewenyu99edwinyjlim
authored
make error tracking troubleshooting even better (#14171)
* make error tracking troubleshooting great * title case * nit * nits * Fix typos * Update contents/docs/error-tracking/common-questions.mdx Co-authored-by: Vincent (Wen Yu) Ge <[email protected]> * Update contents/docs/error-tracking/common-questions.mdx Co-authored-by: Vincent (Wen Yu) Ge <[email protected]> * Update src/components/Docs/SolvedQuestions/index.tsx Co-authored-by: Edwin Lim <[email protected]> * feedback 1 * tweak styling * add style guide sections * use os components, replace placeholder text * Update src/components/AskAIInput/index.tsx Co-authored-by: Edwin Lim <[email protected]> --------- Co-authored-by: PostHog <[email protected]> Co-authored-by: Vincent (Wen Yu) Ge <[email protected]> Co-authored-by: Edwin Lim <[email protected]>
1 parent 44a5fc5 commit 8ae738e

File tree

8 files changed

+440
-50
lines changed

8 files changed

+440
-50
lines changed
Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,133 @@
11
---
2-
title: Error tracking troubleshooting and FAQs
2+
title: Error Tracking troubleshooting
33
---
44

5-
## FAQs
5+
This page covers troubleshooting for Error Tracking. For setup, see the [installation guides](/docs/error-tracking/installation).
66

7-
### How much does error tracking cost?
7+
## Have a question? Ask PostHog AI
88

9-
Your first 100,000 `$exception` events each month are free – i.e. if you never exceed this number, you can use error tracking for free.
9+
<AskAIInput placeholder="Type your question and hit enter..." />
1010

11-
After this, we charge a small amount for each `$exception` event you send. The more events you send, the less each event costs.
11+
## Exceptions not appearing
1212

13-
Go to the [pricing page](/pricing) to use our calculator to get an estimate. You can also view an estimate on [your billing page](https://us.posthog.com/organization/billing).
13+
If PostHog isn't capturing errors:
1414

15-
### Are web workers supported?
15+
1. Use the [SDK Doctor](/docs/sdk-doctor) to verify your SDKs are updated to the latest version
16+
2. Verify **exception capture** is enabled in [project settings](https://app.posthog.com/settings/project-error-tracking#exception-autocapture)
17+
3. Only unhandled exceptions auto-capture. For caught errors, use `posthog.captureException()`:
1618

17-
Yes. Error tracking will work as long as you initialize PostHog in the [web worker](/tutorials/web-worker). You will need to disable any features that rely on the `window` object:
19+
```js
20+
try {
21+
// code that errors
22+
} catch (error) {
23+
posthog.captureException(error)
24+
}
25+
```
1826

19-
```js
20-
posthog.init(token, {
21-
...
22-
autocapture: false,
23-
capture_pageview: false,
24-
capture_pageleave: false,
25-
disable_session_recording: true,
26-
disable_surveys: true,
27-
});
28-
```
27+
4. Wait a few minutes and check [Error Tracking in the PostHog app](https://app.posthog.com/error_tracking). Issues may take a few minutes to update after ingesting new error events
28+
29+
## Source maps not resolving
30+
31+
If stack traces show minified code instead of original source:
32+
33+
1. Verify source maps are uploaded to the correct project by navigating to [Error Tracking](https://app.posthog.com/error_tracking) and selecting **Configure** > **Symbol sets**. You'll also see warnings for missing symbol sets
34+
2. The `release` tag in your SDK config must match the version you uploaded:
2935

30-
To `identify` users in web workers you will need to pass the distinct ID. This can be done via an env variable or sending it via `postMessage` from your main application.
36+
```js
37+
posthog.init('<ph_project_api_key>', {
38+
...
39+
session_recording: {
40+
recordCrossOriginIframes: true,
41+
},
42+
release: 'v1.2.3'
43+
})
44+
```
3145

32-
### Can exceptions be sampled / ignored
46+
3. Source map paths must match your production bundle URLs exactly
47+
4. Upload source maps *before* deploying code that references them
3348

34-
Returning `null` for a given event in the [`before_send`](/docs/libraries/js/features#amending-or-sampling-events) hook will cause it not to be captured. You may want to:
35-
- Drop certain types of exceptions
36-
- Randomly sample a subset of all exceptions
37-
- Sample based on the events properties (e.g. URL or user)
49+
See the [source maps guide](/docs/error-tracking/upload-source-maps/) for upload instructions.
3850

39-
## Troubleshooting
51+
## 'Script error' with no stack trace
4052

41-
### What is a 'Script error.' with no stack traces?
53+
For security purposes, browsers hide error details from scripts loaded from different domains. This shows as `Script error` with no stack trace.
4254

43-
For security purposes, errors sent from a JavaScript file served on a different domain hide the original error to avoid unintentionally leaking sensitive information to any `onerror` handler. This is often the case for third party scripts running on a site and results in an obfuscated 'Script error.' with no associated stack trace.
55+
To fix, add `crossorigin="anonymous"` to your script tags:
4456

45-
To see the actual error, the erroring script needs to be loaded `anonymously` which excludes potentially user-identifying information such as cookies from being transmitted when requesting the file.
57+
```html
58+
<script src="https://your-cdn.com/app.js" crossorigin="anonymous"></script>
59+
```
60+
61+
If the script is within your control, also set the `Access-Control-Allow-Origin` response header to your origin:
4662

4763
```
48-
<script src="https://third-party.domain/script.js" crossorigin="anonymous"></script>
64+
Access-Control-Allow-Origin: https://yourdomain.com
4965
```
5066

51-
It can be somewhat difficult to know which script is causing the error because the captured exception provides no context. There is no solution to this other than to work through a process of elimination.
67+
Or allow any origin:
68+
69+
```
70+
Access-Control-Allow-Origin: *
71+
```
5272

53-
If the script is within your control, you also need to set the `Access-Control-Allow-Origin` response header to include the calling domain. This can be a comma separated list of valid domains or a global wildcard e.g `*`.
73+
You can also use [session recordings](/docs/session-replay) to see what user actions triggered the error.
5474

55-
### What is a 'Non-Error promise rejection' error with no stack traces?
75+
## 'Non-Error promise rejection' with no stack trace
5676

57-
When you do not pass an `Error` object to a rejected promise, the resulting error captured will be a generic 'Non-Error promise rejection' and the stack trace context will not be included. An example of this is:
77+
This happens when you reject a promise with a string instead of an `Error` object. Without an `Error` object, there's no stack trace to capture.
5878

59-
```js
79+
<MultiLanguage>
80+
81+
```js file=Without stack trace
6082
new Promise((resolve, reject) => {
61-
// the captured error will be 'Non-Error promise rejection' without a stack trace
62-
reject('Something went wrong');
83+
reject('Something went wrong'); // String has no stack trace
6384
});
64-
```
6585

66-
The easiest way to resolve this is to always reject promises with an `Error` object:
86+
Promise.reject('Something went wrong');
87+
```
6788

68-
```js
89+
```js file=With stack trace
6990
new Promise((resolve, reject) => {
70-
// the captured error will be 'Something went wrong' with a stack trace
71-
reject(new Error('Something went wrong'));
91+
reject(new Error('Something went wrong')); // Error includes stack trace
7292
});
93+
94+
Promise.reject(new Error('Something went wrong'));
95+
```
96+
97+
</MultiLanguage>
98+
99+
For third-party libraries that reject with strings, wrap the rejection:
100+
101+
```js
102+
somePromise()
103+
.catch(err => {
104+
posthog.captureException(new Error(err))
105+
throw err
106+
})
73107
```
74108

75-
### What is a 'Minified React error' with no stack traces?
109+
## 'Minified React error' with no stack trace
76110

77-
In order to reduce bundle size in production builds React removes useful debugging information from errors thrown by the framework. This results in errors that lack stack traces and look like the following:
111+
In production builds, React removes debugging information to reduce bundle size. Errors look like:
78112

79113
```
80-
Minified React error #123; visit https://reactjs.org/docs/error-decoder.html?invariant=123 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
114+
Minified React error #123; visit https://reactjs.org/docs/error-decoder.html?invariant=123
81115
```
82116

83-
The link provided in the error message can be used to look up the full error message and understand the cause of the error. However, it will not tell you exactly where in your code the error originates from.
117+
To debug:
118+
119+
1. Upload source maps to get readable stack traces. See the [source maps guide](/docs/error-tracking/upload-source-maps/)
120+
2. Visit the error URL in the message to understand what went wrong
121+
3. Watch [session recordings](/docs/session-replay) to see what user actions triggered the error, then reproduce in development
122+
4. Use a development build which includes full error messages. Only use this for debugging, not production
123+
124+
## Solved community questions
84125

85-
One way to debug these kinds of issues is to watch session recordings to see what user actions lead up to the error occurring. From there you can try to reproduce the error by following the same steps in your development environment, where the full stack trace will be available.
126+
<SolvedQuestions
127+
topicLabel="Error Tracking"
128+
pinnedQuestions={[
129+
'code-variables-for-external-libraries-for-python',
130+
'trouble-setting-up-source-map-in-vite-react',
131+
'webpack-turbopack-plugin-getting-sourcemaps-uploaded-to-vercel'
132+
]}
133+
/>

contents/handbook/content/docs-style-guide.mdx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,39 @@ Available props:
217217

218218
The component automatically tracks when users open PostHog AI and includes the current page context.
219219

220+
### AskAIInput
221+
222+
The `<AskAIInput>` component provides a text input for users to ask PostHog AI questions directly within documentation pages. Use this to replace traditional FAQ sections in troubleshooting guides and documentation pages where users frequently have questions. The component opens the PostHog AI chat window with the user's question pre-loaded and includes the current page context. Add a clear h2 heading like "Have a question? Ask PostHog AI" above the component.
223+
224+
> **Note:** Customize the `placeholder` prop per page to provide context-specific guidance. The default is `Ask a question...`
225+
226+
```mdx
227+
## Have a question? Ask PostHog AI
228+
229+
<AskAIInput placeholder="Type your question and hit enter..." />
230+
```
231+
232+
<AskAIInput placeholder="Type your question and hit enter..." />
233+
234+
> See [src/components/AskAIInput/index.tsx](https://github.com/PostHog/posthog.com/blob/master/src/components/AskAIInput/index.tsx) for all available props.
235+
236+
### SolvedQuestions
237+
238+
The `<SolvedQuestions>` component displays resolved community questions from a specific topic. Use this in troubleshooting guides to highlight common issues and their solutions. Find question slugs by visiting the community question page and copying the URL slug.
239+
240+
> **Note:** Use the `pinnedQuestions` prop to manually curate which questions appear. When provided, the component shows only those questions. If not provided, it shows recent solved posts.
241+
242+
```mdx
243+
<SolvedQuestions
244+
topicLabel="Error Tracking"
245+
pinnedQuestions={[
246+
'code-variables-for-external-libraries-for-python',
247+
'trouble-setting-up-source-map-in-vite-react',
248+
'webpack-turbopack-plugin-getting-sourcemaps-uploaded-to-vercel'
249+
]}
250+
/>
251+
```
252+
220253
### Steps
221254

222255
Use the `<Steps>` component for content that walks the reader through a strict sequence of instructions. Think how-to guides or step-by-step tutorials.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Use to replace FAQs with an Ask PostHog AI input interface, let users choose their own FAQs. Add a h2 heading "Have a question? Ask PostHog AI" above this component in the MDX file
2+
3+
import React, { useState } from 'react'
4+
import { IconSparkles } from '@posthog/icons'
5+
import { useLayoutData } from 'components/Layout/hooks'
6+
import usePostHog from 'hooks/usePostHog'
7+
import { useApp } from '../../context/App'
8+
import { useLocation } from '@reach/router'
9+
import { useWindow } from '../../context/Window'
10+
import OSButton from 'components/OSButton'
11+
12+
interface AskAIInputProps {
13+
placeholder?: string
14+
className?: string
15+
}
16+
17+
const DEFAULT_PLACEHOLDER = 'Ask a question...'
18+
19+
export default function AskAIInput({ placeholder = DEFAULT_PLACEHOLDER, className = '' }: AskAIInputProps) {
20+
const [question, setQuestion] = useState('')
21+
const posthog = usePostHog()
22+
const { compact } = useLayoutData()
23+
const { openNewChat } = useApp()
24+
const { appWindow } = useWindow()
25+
const location = useLocation()
26+
27+
const handleSubmit = () => {
28+
if (!question.trim()) return
29+
posthog?.capture('Opened MaxAI chat', { source: 'AskAI input' })
30+
openNewChat({
31+
path: `ask-max-${location.pathname}`,
32+
initialQuestion: question,
33+
context: [
34+
{
35+
type: 'page',
36+
value: {
37+
path: appWindow?.path || '',
38+
label: appWindow?.meta?.title || '',
39+
},
40+
},
41+
],
42+
})
43+
}
44+
45+
if (compact) return null
46+
47+
return (
48+
<div className={`flex gap-2 items-center ${className}`}>
49+
<input
50+
type="text"
51+
value={question}
52+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setQuestion(e.target.value)}
53+
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
54+
if (e.key === 'Enter') {
55+
handleSubmit()
56+
}
57+
}}
58+
placeholder={placeholder}
59+
className="flex-1 bg-primary border border-primary rounded px-2.5 py-2.5 text-[15px] ring-0 focus:ring-0"
60+
/>
61+
<OSButton variant="secondary" size="md" onClick={handleSubmit} icon={<IconSparkles />} iconPosition="right">
62+
Ask PostHog AI
63+
</OSButton>
64+
</div>
65+
)
66+
}

src/components/CodeBlock/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ export const CodeBlock = ({
388388
href={`${generateSQLEditorLink(activeLanguage.code)}`}
389389
target="_blank"
390390
rel="noopener noreferrer"
391-
className="inline-flex items-center gap-1 whitespace-nowrap text-primary/50 hover:text-primary/75 dark:text-primary-dark/50 dark:hover:text-primary-dark/75 px-1 py-1 hover:bg-light dark:hover:bg-dark border border-transparent hover:border-light dark:hover:border-dark rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
391+
className="inline-flex items-center gap-1 whitespace-nowrap text-muted hover:text-secondary px-1 py-1 bg-transparent hover:bg-border border border-transparent hover:border rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
392392
>
393393
Run in PostHog
394394
<IconArrowUpRight className="w-4 h-4" />
@@ -402,7 +402,7 @@ export const CodeBlock = ({
402402
onClick={() =>
403403
handleAskAboutCode(activeLanguage.code, activeLanguage.language)
404404
}
405-
className="ask-posthog-ai-code-snippet inline-flex items-center gap-1 text-primary/50 hover:text-primary/75 dark:text-primary-dark/50 dark:hover:text-primary-dark/75 px-1 py-1 hover:bg-light dark:hover:bg-dark border border-transparent hover:border-light dark:hover:border-dark rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
405+
className="ask-posthog-ai-code-snippet inline-flex items-center gap-1 text-muted hover:text-secondary px-1 py-1 bg-transparent hover:bg-border border border-transparent hover:border rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
406406
>
407407
<span className="hidden group-hover/askai:inline whitespace-nowrap text-sm">
408408
PostHog AI
@@ -416,7 +416,7 @@ export const CodeBlock = ({
416416
<div className="relative flex items-center justify-center px-1">
417417
<button
418418
onClick={() => copyToClipboard(activeLanguage.code)}
419-
className="text-muted hover:text-secondary px-1 py-1 hover:bg-light dark:hover:bg-dark border border-transparent hover:border rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
419+
className="text-muted hover:text-secondary px-1 py-1 bg-transparent hover:bg-border border border-transparent hover:border rounded relative hover:scale-[1.02] active:top-[.5px] active:scale-[.99]"
420420
title="Copy to clipboard"
421421
>
422422
<svg

0 commit comments

Comments
 (0)