fix(init): show why initialization failed instead of a bare 500 - #674
Merged
Merged
Conversation
The setup wizard only surfaced the backend's generic message, so a storage misconfiguration (invalid DB_DRIVER x DB_FORMAT pair, missing binding, read failure) ended as an unexplained failure toast with no way forward. - request: keep the response body on HTTP errors and prefer the server's message, so callers can read structured reasons (data.code / data.reason) instead of 'Request failed with status code 500'. - init page: remember and display the failure reason + error code inline on the admin-account step (the step users are returned to), and show the backend-reported storage problem (/public/init_status storage_error, db_load_error) on every step. - types: add InitSetupError, InitStatus.storage_error/db_load_error/db_trusted and EnvCheck.storage.error_code/error_message. - i18n: add the new labels to the English source dictionary (other locales fall back to English). Pairs with the backend change that reports STORAGE_INVALID_COMBINATION and per-driver 'what is required' hints; without it the wizard could not distinguish 'combination is wrong' from 'binding is missing'. Verified with tsc (no errors in the touched files) and prettier. A full vite build cannot run in this sandbox (vite-plugin-static-copy triggers the environment's bulk-delete guard on the existing dist/), so please run pnpm build locally.
The previous commit attached data to every error response. An invariant documented in multipart.ts relies on a transport-level failure resolving to a bare {code, message} WITHOUT a data key (a real server envelope always carries one) to tell retryable transport failures from server verdicts, including flow control (429/409). Adding data: null for CDN/gateway errors (HTML body) would have made those look like envelopes and changed the upload retry / flow-control branches.
Only attach data when the server actually sent a non-null one: the mpRequest probe stays intact while the init wizard still gets the structured reason (data.code / data.reason) it needs. multipart.ts:59 is the only place in the codebase using the data in resp probe.
Verified: prettier clean, tsc reports no errors in the touched files.
…river The backend now degrades to the auto-detected backend when the configured driver is unavailable (instead of 503-ing every request) and reports that as a warning, together with a one-line suggestion for both failures and fallbacks. Surface both in the setup wizard. - types: EnvCheckIssue.suggestion, EnvCheck.storage.suggestion, InitStatus.storage_warning / storage_suggestion, InitSetupError.suggestion. - env check panel: render "How to fix" above the docs link, so the action cannot be lost inside a long multi-line reason. - wizard: warning banner for a fallback (site usable, but data lands on a different backend than configured) and the suggestion inside the setup-failure box. - i18n: env_fix_title / storage_warning_title (English source, other locales fall back to English).
The backend no longer switches to another backend when the configured driver is unavailable, so there is nothing to warn about: a misconfigured driver is reported as an error, including the driver auto-detection would have picked and a one-line suggestion. The existing problem banner and the env-check panel already render that. - types: drop InitStatus.storage_warning - init page: drop the warning signal/banner; keep the suggestion line (and EnvCheckIssue.suggestion) for real configuration errors - i18n: drop storage_warning_title
…rose The backend now exposes `summary` (a complete one-line sentence) next to the full diagnostic text, and reports a single issue per problem. Render that: - env check panel: show issue.summary (fall back to message for older backends) so a box no longer reads like "Storage driver is not configured correctly: DB_DRIVER is set to "do", but that driver is not availa…" - setup failure box: prefer failure.summary over the truncated reason - types: EnvCheckIssue.summary, EnvCheck.storage.summary, InitSetupError.summary
Step 1 rendered the problem twice: the banner (from /public/init_status) and the environment panel (from /public/env_check) both showed the same reason and the same "How to fix", which reads like two separate problems. - the banner now renders only on the steps where the panel is not visible (2/3); when the backend has no self-check at all it still shows on step 1 - the "once the environment is ready, continue..." line is hidden while the environment is blocked, since the panel already says "Resolve the issues above to continue"
|
大佬 我怎么用你这个修复好的 |
jyxjjj
approved these changes
Sep 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(init): show why initialization failed instead of a bare 500
Base:
main← Compare:fix/init-error-visibilityCommit:
c5f6671· Files changed: 4 (+126 / −3)Open PR: https://github.com/OpenListTeam/OpenList-Frontend/pull/new/fix/init-error-visibility
配套后端 PR:
fix/init-setup-empty-store(OpenList-Worker,8daf341+1dba9ad)https://github.com/OpenListTeam/OpenList-Worker/pull/new/fix/init-setup-empty-store
Summary / 摘要
初始化失败时,安装向导只弹一条 toast,用户拿不到任何可操作信息:后端返回的
message被通用文案覆盖,结构化原因(data.code/data.reason)在请求层就被丢弃,页面也没有持久展示位。用户看到的就是「点了初始化 → 失败 → 不知道为什么」。
本 PR 让向导把原因说清楚:失败原因与错误码内联展示在「管理员账号」步骤;后端自报
的存储问题(
init_status.storage_error/db_load_error)在任何步骤都可见;HTTP错误不再丢掉响应体与服务端文案。
When initialization fails the wizard only showed a transient toast: the server's
structured reason (
data.code/data.reason) was dropped by the request layerand the page had nowhere to display it. This PR surfaces the reason inline, keeps
the backend-reported storage problem visible on every step, and stops discarding
the response body on HTTP errors.
Behavior Changes / 行为变化
User-visible behavior changes / 用户可感知的行为变化:
初始化失败后回到「管理员账号」步骤时,会持续展示具体原因与错误码:
后端自报的存储问题在所有步骤都可见(含修复提示),不再出现「未初始化 + 无原因」:
环境自检面板(
EnvCheck.tsx)无需改动即受益:issue 的message现在包含后端给出的具体原因,并新增
STORAGE_INVALID_COMBINATION这条(含文档链接)。非法组合不再是「自检全绿 → 提交 → 500」。
HTTP 错误的提示文案改为服务端文案(例如「database is not readable…」),
而不是 axios 的
Request failed with status code 500。Important implementation changes / 重要实现变化:
src/utils/request.ts:错误拦截器保留响应体并优先使用服务端message(
{ code, message, data }),网络错误/超时仍回退 axios 的 message。这是本 PR 能让上层拿到
data.reason的前提。src/pages/init/index.tsx:failure():失败时记录data.code/data.reason(reason缺失时回退服务端
message),成功提交时清空;storageIssue():onMount读取/public/init_status的storage_error/db_load_error,在步骤指示器下方常驻展示;src/types/init.ts:新增InitSetupError;InitStatus增加storage_error/db_load_error/db_trusted;EnvCheck.storage增加error_code/error_message。src/lang/en/init.json:新增 4 个键(error_title/error_code/storage_issue_title/storage_issue_hint)。This PR has breaking changes.
/ 此 PR 包含破坏性变更。
This PR changes public API, config, storage format, or migration behavior.
/ 此 PR 修改了公开 API、配置、存储格式或迁移行为。
This PR requires corresponding changes in related repositories.
/ 此 PR 需要关联仓库同步修改。(后端
OpenList-Worker)Related repository PRs / 关联仓库 PR:
Related Issues / 关联 Issue
Relates to OpenListTeam/OpenList-Worker#62 —— 该 issue 的三条现象中,「全新空存储
向导 500」「配置 ADMIN_PASS 仍跳 /@init」由配套后端 PR 修复;本 PR 负责让用户在
页面上看见失败原因(issue 正文里「期望:应能通过向导完成首次初始化 / 至少给出
可操作提示」的前端部分)。
Root Cause / 根因分析
src/utils/request.ts的错误分支只返回{ code: error.response?.status, message: error.message },服务端的message与data全部丢失,前端无论怎么改都拿不到原因。notify.error(...)弹 toast,随后回到第 2 步,页面没有任何地方保留失败信息;用户重试时只能靠猜。
/public/init_status返回storage_error/db_load_error(见配套 PR),但前端从未读取,导致「存储不可用」只能表现为「未初始化」加一个 500。
Testing / 测试
npx tsc --noEmit -p tsconfig.json:改动文件(utils/request.ts、types/init.ts、pages/init/index.tsx)无错误(仓库在main上本来就有若干与本次无关的既有类型错误,例如 Monaco / archive 预览相关)
npx prettier --check(改动文件):通过pnpm build:需要本地执行。本机沙箱对批量删除有保护,vite-plugin-static-copy覆盖既有dist/(500+ 文件)时被拦截(
SAFE_DELETE_BULK_CONFIRM_REQUIRED),与本次改动无关DB_DRIVER=kv+DB_FORMAT=sql(无效组合)→ 第 1 步红框列出非法组合 +STORAGE_INVALID_COMBINATION文档链接;若强行提交,第 2 步显示同名原因与错误码;DB_DRIVER=d1但未绑定 D1 → 第 1 步提示需要d1_databases;init_status的
storage_error常驻显示;STORAGE_READ_FAILED原因;env_check/ 无storage_error)→ 步骤仍为两步,界面不出现空白的红框,行为与改动前一致。
Reviewer Notes / 审阅提示
request.ts的影响面是全局的:所有失败请求的提示文案都会从 axios 文案改为服务端文案,并多出一个
data字段(仅在错误路径)。这是有意为之(服务端文案更有用),但请确认可接受。
Resp<T>.data的类型仍是T;错误路径下实际是InitSetupError,页面里用(resp as any)?.data as InitSetupError | null取用,避免动
Resp的通用类型(那会波及全部调用方)。reason回退为服务端message(或原有 toast),不会出现空框或报错。src/lang/en/是唯一被 git 跟踪的语言目录,其余语言由 Crowdin 生成(
.gitignore忽略)。本 PR 只加英文键,其它语言按既有机制回退英文;中文翻译需在Crowdin 侧同步。
EnvCheck.tsx:它已经按issues[]渲染「消息 + 文档链接」,后端把原因写进message后面板自动受益,无需重复实现。