{"record":{"id":"5456d010fedd5603","repo":"flipped-aurora/gin-vue-admin","slug":"w-5456d0","errorCode":null,"errorMessage":"数据库已提交，前端文件发布失败: %w","messagePattern":"数据库已提交，前端文件发布失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_task.go","lineNumber":165,"sourceCode":"}\n\nfunc commitAutoCodeFileTask(task *autoCodeFileTask, publish autoCodeFilePublisher, persist func() error) error {\n\tif task == nil || publish == nil || persist == nil {\n\t\treturn errors.New(\"自动代码任务提交参数不能为空\")\n\t}\n\tdefer task.cleanup()\n\n\tbackendApplied, err := task.apply(autoCodeTaskBackend, publish)\n\tif err != nil {\n\t\treturn joinAutoCodeRollbackError(err, task.rollback(backendApplied))\n\t}\n\tif err = persist(); err != nil {\n\t\treturn joinAutoCodeRollbackError(err, task.rollback(backendApplied))\n\t}\n\tfrontendApplied, err := task.apply(autoCodeTaskFrontend, publish)\n\tif err != nil {\n\t\treturn joinAutoCodeRollbackError(\n\t\t\tfmt.Errorf(\"数据库已提交，前端文件发布失败: %w\", err),\n\t\t\ttask.rollback(frontendApplied),\n\t\t)\n\t}\n\treturn nil\n}\n\nfunc (task *autoCodeFileTask) apply(kind string, publish autoCodeFilePublisher) ([]int, error) {\n\tapplied := make([]int, 0, len(task.files))\n\tfor index := range task.files {\n\t\tfile := &task.files[index]\n\t\tif file.Kind != kind {\n\t\t\tcontinue\n\t\t}\n\t\tpublished, err := publish(file)\n\t\tif err != nil {\n\t\t\treturn applied, err\n\t\t}\n\t\tif published {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_task.go#L147-L183","documentation":"This error wraps a failure that occurred while publishing the frontend file batch of an auto-generated code task, raised AFTER the database transaction has already been committed. commitAutoCodeFileTask applies backend files first, persists to the DB, then applies frontend files; if the frontend publish fails the DB write cannot be undone, so the error is annotated to make that irreversible state explicit while the already-applied frontend files are rolled back to their pre-task content.","triggerScenarios":"Calling the auto-code commit flow (commitAutoCodeFileTask with publishPreparedAutoCodeFile) when any frontend target file publish fails: the target was externally modified since preparation (errAutoCodeFileConflict), creating the target directory failed, the atomic rename failed, or hashing the target failed.","commonSituations":"A developer or editor touched a generated web/ file between task preparation and commit; the frontend root directory is read-only or owned by another user; a target path became a directory or was deleted; cross-device rename issues (staging dir and target on different filesystems).","solutions":["Check the wrapped cause: if it is '自动代码目标文件已被外部修改', restore or manually reconcile the externally changed target, then re-run the code generation task","Verify the web/ root and target directories are writable by the server process (permissions/ownership)","Ensure no process is holding locks on target files (editors, file watchers) during generation","Note the DB row is already committed: inspect the generated record and re-run only the file-publish phase or manually create the frontend files if rollback also failed"],"exampleFix":"// before: fixing by manually editing generated files then retrying blindly\n$ vim web/src/view/.../xxx.vue  # target drifted -> conflict on retry\n\n// after: revert external edits so hash matches prepared BeforeHash, then re-run\n$ git checkout -- web/src/view/.../xxx.vue\n# re-trigger auto-code commit; frontend publish now succeeds","handlingStrategy":"try-catch","validationCode":"func guardFrontendPublish(files []string) error {\n\tfor _, f := range files {\n\t\tinfo, err := os.Stat(filepath.Dir(f))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"missing dir %s: %w\", filepath.Dir(f), err)\n\t\t}\n\t\tif !info.IsDir() || info.Mode().Perm()&0o200 == 0 {\n\t\t\treturn fmt.Errorf(\"dir %s not writable\", filepath.Dir(f))\n\t\t}\n\t\tif _, err := os.Stat(f); err == nil {\n\t\t\tif h, _ := hashFile(f); h != recordedBeforeHash[f] {\n\t\t\t\treturn fmt.Errorf(\"%s externally modified\", f)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isConflictErr(err error) bool {\n\treturn errors.Is(err, errAutoCodeFileConflict)\n}","tryCatchPattern":"if err := commitAutoCodeFileTask(task, publishPreparedAutoCodeFile, persist); err != nil {\n\tif errors.Is(err, errAutoCodeFileConflict) {\n\t\t// reconcile the named target path, then retry the whole task\n\t} else {\n\t\t// DB already committed: alert operator, inspect generated record\n\t\tlog.Printf(\"frontend publish failed after DB commit: %v\", err)\n\t}\n}","preventionTips":["Do not hand-edit generated files while a generation task is pending; change the templates instead","Run the server process with write access to the whole project root (server/ and web/)","Avoid git pull/stash/checkout and file watchers rewriting targets during generation","Treat this error as a partial-failure signal: the DB write succeeded even though files may be rolled back"],"tags":["file-publish","partial-failure","autocode","atomic-write","database-committed"],"backgroundTag":"frontend-publish-after-db-commit-failure","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}