Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
a6981a06
提交
a6981a06
authored
4月 16, 2025
作者:
Will Chen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve preview iframe error handling: show new errors after dismiss & UX readability
上级
041d3614
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
19 行增加
和
15 行删除
+19
-15
PreviewIframe.tsx
src/components/preview_panel/PreviewIframe.tsx
+15
-14
PreviewPanel.tsx
src/components/preview_panel/PreviewPanel.tsx
+4
-1
没有找到文件。
src/components/preview_panel/PreviewIframe.tsx
浏览文件 @
a6981a06
...
...
@@ -35,7 +35,7 @@ import { showError } from "@/lib/toast";
import
{
SandboxConfig
}
from
"@/ipc/ipc_types"
;
interface
ErrorBannerProps
{
error
:
string
|
null
;
error
:
string
|
undefined
;
onDismiss
:
()
=>
void
;
onAIFix
:
()
=>
void
;
}
...
...
@@ -44,11 +44,11 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
if
(
!
error
)
return
null
;
return
(
<
div
className=
"absolute top-2 left-2 right-2 z-10 bg-red-50 dark:bg-red-950
/50
border border-red-200 dark:border-red-800 rounded-md shadow-sm p-2"
>
<
div
className=
"absolute top-2 left-2 right-2 z-10 bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded-md shadow-sm p-2"
>
{
/* Close button in top left */
}
<
button
onClick=
{
onDismiss
}
className=
"absolute top-1 left-1 p-1 hover:bg-red-100 dark:hover:bg-red-900
/50
rounded"
className=
"absolute top-1 left-1 p-1 hover:bg-red-100 dark:hover:bg-red-900 rounded"
>
<
X
size=
{
14
}
className=
"text-red-500 dark:text-red-400"
/>
</
button
>
...
...
@@ -60,11 +60,11 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
{
/* Tip message */
}
<
div
className=
"mt-2 px-6"
>
<
div
className=
"relative p-2 bg-red-100 dark:bg-red-900
/50
rounded-sm flex gap-1 items-center"
>
<
div
className=
"relative p-2 bg-red-100 dark:bg-red-900 rounded-sm flex gap-1 items-center"
>
<
div
>
<
Lightbulb
size=
{
16
}
className=
" text-red-800 dark:text-red-300"
/>
</
div
>
<
span
className=
"text-sm text-red-700 dark:text-red-
4
00"
>
<
span
className=
"text-sm text-red-700 dark:text-red-
2
00"
>
<
span
className=
"font-medium"
>
Tip:
</
span
>
Check if refreshing the
page or restarting the app fixes the error.
</
span
>
...
...
@@ -88,10 +88,10 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
// Preview iframe component
export
const
PreviewIframe
=
({
loading
,
error
,
loadingErrorMessage
,
}:
{
loading
:
boolean
;
error
:
Error
|
null
;
loadingErrorMessage
:
string
|
undefined
;
})
=>
{
const
selectedAppId
=
useAtomValue
(
selectedAppIdAtom
);
const
{
appUrl
}
=
useAtomValue
(
appUrlAtom
);
...
...
@@ -100,8 +100,9 @@ export const PreviewIframe = ({
// State to trigger iframe reload
const
[
reloadKey
,
setReloadKey
]
=
useState
(
0
);
const
[
iframeError
,
setIframeError
]
=
useState
<
string
|
null
>
(
null
);
const
[
showError
,
setShowError
]
=
useState
(
true
);
const
[
errorMessage
,
setErrorMessage
]
=
useState
<
string
|
undefined
>
(
loadingErrorMessage
);
const
setInputValue
=
useSetAtom
(
chatInputValueAtom
);
const
[
availableRoutes
,
setAvailableRoutes
]
=
useState
<
Array
<
{
path
:
string
;
label
:
string
}
>
...
...
@@ -171,7 +172,7 @@ export const PreviewIframe = ({
if
(
type
===
"window-error"
)
{
const
errorMessage
=
`Error in
${
payload
.
filename
}
(line
${
payload
.
lineno
}
, col
${
payload
.
colno
}
):
${
payload
.
message
}
`
;
console
.
error
(
"Iframe error:"
,
errorMessage
);
set
IframeError
(
errorMessage
);
set
ErrorMessage
(
errorMessage
);
setAppOutput
((
prev
)
=>
[
...
prev
,
{
...
...
@@ -183,7 +184,7 @@ export const PreviewIframe = ({
}
else
if
(
type
===
"unhandled-rejection"
)
{
const
errorMessage
=
`Unhandled Promise Rejection:
${
payload
.
reason
}
`
;
console
.
error
(
"Iframe unhandled rejection:"
,
errorMessage
);
set
IframeError
(
errorMessage
);
set
ErrorMessage
(
errorMessage
);
setAppOutput
((
prev
)
=>
[
...
prev
,
{
...
...
@@ -412,10 +413,10 @@ export const PreviewIframe = ({
<
div
className=
"relative flex-grow "
>
<
ErrorBanner
error=
{
showError
?
error
?.
message
||
iframeError
:
null
}
onDismiss=
{
()
=>
set
ShowError
(
false
)
}
error=
{
errorMessage
}
onDismiss=
{
()
=>
set
ErrorMessage
(
undefined
)
}
onAIFix=
{
()
=>
{
setInputValue
(
`Fix the error in ${error
?.message || iframeError
}`
);
setInputValue
(
`Fix the error in ${error
Message
}`
);
}
}
/>
...
...
src/components/preview_panel/PreviewPanel.tsx
浏览文件 @
a6981a06
...
...
@@ -162,7 +162,10 @@ export function PreviewPanel() {
<
Panel
id=
"content"
minSize=
{
30
}
>
<
div
className=
"h-full overflow-y-auto"
>
{
previewMode
===
"preview"
?
(
<
PreviewIframe
loading=
{
loading
}
error=
{
error
}
/>
<
PreviewIframe
loading=
{
loading
}
loadingErrorMessage=
{
error
?.
message
}
/>
)
:
(
<
CodeView
loading=
{
loading
}
error=
{
error
}
app=
{
app
}
/>
)
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论