Skip to content

Commit fc80b23

Browse files
authored
feat(dashboard): show error details in development mode (#14875)
Show error message and stack trace with copy button in the admin dashboard when in dev mode <img width="903" height="621" alt="CleanShot 2026-03-11 at 16 48 01" src="https://github.com/user-attachments/assets/e2a576ab-7f16-4c51-b450-e1f01350babf" />
1 parent c7e799d commit fc80b23

File tree

2 files changed

+85
-2
lines changed

2 files changed

+85
-2
lines changed

.changeset/short-games-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/dashboard": patch
3+
---
4+
5+
feat(dashboard): show error details in development mode

packages/admin/dashboard/src/components/utilities/error-boundary/error-boundary.tsx

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { ExclamationCircle } from "@medusajs/icons"
2-
import { Text } from "@medusajs/ui"
1+
import { ExclamationCircle, SquareTwoStack } from "@medusajs/icons"
2+
import { toast, Text, IconButton, Tooltip } from "@medusajs/ui"
3+
import copy from "copy-to-clipboard"
34
import { useTranslation } from "react-i18next"
45
import { Navigate, useLocation, useRouteError } from "react-router-dom"
56

@@ -20,6 +21,11 @@ export const ErrorBoundary = () => {
2021
code = error.status ?? null
2122
}
2223

24+
// In development mode, show detailed error information
25+
const isDevelopment = process.env.NODE_ENV === "development"
26+
const errorMessage = error instanceof Error ? error.message : String(error)
27+
const errorStack = error instanceof Error ? error.stack : undefined
28+
2329
/**
2430
* Log error in development mode.
2531
*
@@ -28,6 +34,22 @@ export const ErrorBoundary = () => {
2834
*/
2935
if (process.env.NODE_ENV === "development") {
3036
console.error(error)
37+
const fileDetails = errorStack?.split("\n")[1].trim()
38+
const filename = fileDetails?.match(/([^\/\\?]+)(?:\?[^:]*)?:\d+:\d+\)/)?.[1] || "unknown"
39+
const lineno = fileDetails?.match(/(?:\?[^:]*)?:(\d+):\d+\)/)?.[1] || "unknown"
40+
const colno = fileDetails?.match(/(?:\?[^:]*)?:\d+:(\d+)\)/)?.[1] || "unknown"
41+
window.parent.postMessage({
42+
data: {
43+
type: "CONSOLE_OUTPUT",
44+
level: "error",
45+
message: errorMessage,
46+
stack: errorStack,
47+
logged_at: new Date().toISOString(),
48+
filename,
49+
lineno,
50+
colno,
51+
}
52+
}, "*")
3153
}
3254

3355
let title: string
@@ -52,6 +74,17 @@ export const ErrorBoundary = () => {
5274
break
5375
}
5476

77+
const handleCopyError = () => {
78+
const errorText = `Error: ${errorMessage}\n\n${errorStack || "No stack trace available"}`
79+
const success = copy(errorText)
80+
81+
if (success) {
82+
toast.success("Error details copied to clipboard")
83+
} else {
84+
toast.error("Failed to copy error details")
85+
}
86+
}
87+
5588
return (
5689
<div className="flex size-full min-h-[calc(100vh-57px-24px)] items-center justify-center">
5790
<div className="flex flex-col gap-y-6">
@@ -69,6 +102,51 @@ export const ErrorBoundary = () => {
69102
</Text>
70103
</div>
71104
</div>
105+
{isDevelopment && errorMessage && (
106+
<div className="bg-ui-bg-disabled border-ui-border-subtle max-w-3xl overflow-scroll max-h-[400px] rounded-lg border p-4">
107+
<div className="flex flex-col gap-y-4">
108+
<div className="flex items-center justify-between">
109+
<Text
110+
size="small"
111+
weight="plus"
112+
className="text-ui-fg-base"
113+
>
114+
Error Details (Development Mode)
115+
</Text>
116+
<Tooltip content="Copy error details">
117+
<IconButton
118+
onClick={handleCopyError}
119+
variant="transparent"
120+
>
121+
<SquareTwoStack className="text-ui-fg-muted" />
122+
</IconButton>
123+
</Tooltip>
124+
</div>
125+
<div>
126+
<Text
127+
size="xsmall"
128+
className="text-ui-fg-subtle font-mono break-words"
129+
>
130+
{errorMessage}
131+
</Text>
132+
</div>
133+
{errorStack && (
134+
<div>
135+
<Text
136+
size="small"
137+
weight="plus"
138+
className="text-ui-fg-base mb-2"
139+
>
140+
Stack Trace
141+
</Text>
142+
<pre className="text-ui-fg-subtle overflow-auto whitespace-pre-wrap break-words text-xs">
143+
{errorStack}
144+
</pre>
145+
</div>
146+
)}
147+
</div>
148+
</div>
149+
)}
72150
</div>
73151
</div>
74152
)

0 commit comments

Comments
 (0)