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"
34import { useTranslation } from "react-i18next"
45import { 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