Emit clean stack traces from iframe (#63)
This commit is contained in:
@@ -45,7 +45,9 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
|
||||
|
||||
{/* Error message in the middle */}
|
||||
<div className="px-6 py-1 text-sm">
|
||||
<div className="text-red-700 dark:text-red-300 text-wrap">{error}</div>
|
||||
<div className="text-red-700 dark:text-red-300 text-wrap font-mono whitespace-pre-wrap break-words text-xs">
|
||||
{error}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tip message */}
|
||||
@@ -159,8 +161,16 @@ export const PreviewIframe = ({
|
||||
|
||||
const { type, payload } = event.data;
|
||||
|
||||
if (type === "window-error") {
|
||||
const errorMessage = `Error in ${payload.filename} (line ${payload.lineno}, col ${payload.colno}): ${payload.message}`;
|
||||
if (
|
||||
type === "window-error" ||
|
||||
type === "unhandled-rejection" ||
|
||||
type === "iframe-sourcemapped-error"
|
||||
) {
|
||||
const stack =
|
||||
type === "iframe-sourcemapped-error"
|
||||
? payload.stack.split("\n").slice(0, 1).join("\n")
|
||||
: payload.stack;
|
||||
const errorMessage = `Error ${payload.message}\nStack trace: ${stack}`;
|
||||
console.error("Iframe error:", errorMessage);
|
||||
setErrorMessage(errorMessage);
|
||||
setAppOutput((prev) => [
|
||||
@@ -171,18 +181,6 @@ export const PreviewIframe = ({
|
||||
appId: selectedAppId!,
|
||||
},
|
||||
]);
|
||||
} else if (type === "unhandled-rejection") {
|
||||
const errorMessage = `Unhandled Promise Rejection: ${payload.reason}`;
|
||||
console.error("Iframe unhandled rejection:", errorMessage);
|
||||
setErrorMessage(errorMessage);
|
||||
setAppOutput((prev) => [
|
||||
...prev,
|
||||
{
|
||||
message: `Iframe unhandled rejection: ${errorMessage}`,
|
||||
type: "client-error",
|
||||
appId: selectedAppId!,
|
||||
},
|
||||
]);
|
||||
} else if (type === "pushState" || type === "replaceState") {
|
||||
console.debug(`Navigation event: ${type}`, payload);
|
||||
|
||||
@@ -201,10 +199,6 @@ export const PreviewIframe = ({
|
||||
newHistory[currentHistoryPosition] = payload.newUrl;
|
||||
setNavigationHistory(newHistory);
|
||||
}
|
||||
|
||||
// Update navigation buttons state
|
||||
setCanGoBack(currentHistoryPosition > 0);
|
||||
setCanGoForward(currentHistoryPosition < navigationHistory.length - 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -212,6 +206,12 @@ export const PreviewIframe = ({
|
||||
return () => window.removeEventListener("message", handleMessage);
|
||||
}, [navigationHistory, currentHistoryPosition, selectedAppId]);
|
||||
|
||||
useEffect(() => {
|
||||
// Update navigation buttons state
|
||||
setCanGoBack(currentHistoryPosition > 0);
|
||||
setCanGoForward(currentHistoryPosition < navigationHistory.length - 1);
|
||||
}, [navigationHistory, currentHistoryPosition]);
|
||||
|
||||
// Initialize navigation history when iframe loads
|
||||
useEffect(() => {
|
||||
if (appUrl) {
|
||||
|
||||
Reference in New Issue
Block a user