异常处理系统
目录
简介
CapCut Mate 是一个基于 Python 和 Electron 的视频编辑工具,提供了完整的异常处理系统来确保应用程序的稳定性和可靠性。该系统采用分层设计,涵盖了从 API 层到桌面客户端的全方位异常管理。
异常处理系统的核心目标是:
- 提供统一的错误响应格式
- 支持多语言错误信息
- 实现优雅的错误恢复机制
- 确保系统在各种异常情况下都能保持稳定运行
项目结构
项目采用模块化的架构设计,异常处理系统分布在多个层次中:
#mermaid-svg-3RsuUfMKqZ4oob9q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3RsuUfMKqZ4oob9q .error-icon{fill:#552222;}#mermaid-svg-3RsuUfMKqZ4oob9q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3RsuUfMKqZ4oob9q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3RsuUfMKqZ4oob9q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3RsuUfMKqZ4oob9q .marker.cross{stroke:#333333;}#mermaid-svg-3RsuUfMKqZ4oob9q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3RsuUfMKqZ4oob9q p{margin:0;}#mermaid-svg-3RsuUfMKqZ4oob9q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster-label text{fill:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster-label span{color:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster-label span p{background-color:transparent;}#mermaid-svg-3RsuUfMKqZ4oob9q .label text,#mermaid-svg-3RsuUfMKqZ4oob9q span{fill:#333;color:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q .node rect,#mermaid-svg-3RsuUfMKqZ4oob9q .node circle,#mermaid-svg-3RsuUfMKqZ4oob9q .node ellipse,#mermaid-svg-3RsuUfMKqZ4oob9q .node polygon,#mermaid-svg-3RsuUfMKqZ4oob9q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3RsuUfMKqZ4oob9q .rough-node .label text,#mermaid-svg-3RsuUfMKqZ4oob9q .node .label text,#mermaid-svg-3RsuUfMKqZ4oob9q .image-shape .label,#mermaid-svg-3RsuUfMKqZ4oob9q .icon-shape .label{text-anchor:middle;}#mermaid-svg-3RsuUfMKqZ4oob9q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3RsuUfMKqZ4oob9q .rough-node .label,#mermaid-svg-3RsuUfMKqZ4oob9q .node .label,#mermaid-svg-3RsuUfMKqZ4oob9q .image-shape .label,#mermaid-svg-3RsuUfMKqZ4oob9q .icon-shape .label{text-align:center;}#mermaid-svg-3RsuUfMKqZ4oob9q .node.clickable{cursor:pointer;}#mermaid-svg-3RsuUfMKqZ4oob9q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3RsuUfMKqZ4oob9q .arrowheadPath{fill:#333333;}#mermaid-svg-3RsuUfMKqZ4oob9q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3RsuUfMKqZ4oob9q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3RsuUfMKqZ4oob9q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3RsuUfMKqZ4oob9q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3RsuUfMKqZ4oob9q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3RsuUfMKqZ4oob9q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster text{fill:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q .cluster span{color:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3RsuUfMKqZ4oob9q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3RsuUfMKqZ4oob9q rect.text{fill:none;stroke-width:0;}#mermaid-svg-3RsuUfMKqZ4oob9q .icon-shape,#mermaid-svg-3RsuUfMKqZ4oob9q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3RsuUfMKqZ4oob9q .icon-shape p,#mermaid-svg-3RsuUfMKqZ4oob9q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3RsuUfMKqZ4oob9q .icon-shape .label rect,#mermaid-svg-3RsuUfMKqZ4oob9q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3RsuUfMKqZ4oob9q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3RsuUfMKqZ4oob9q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3RsuUfMKqZ4oob9q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工具层
桌面客户端层
API 层
FastAPI 应用
中间件层
业务服务层
Electron 主进程
预加载脚本
IPC 处理器
日志记录器
异常定义
核心组件
自定义错误枚举系统
异常处理系统的核心是一个强大的错误枚举类,支持中英文双语错误信息:
#mermaid-svg-LxczHbQPtTrhJNBv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LxczHbQPtTrhJNBv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LxczHbQPtTrhJNBv .error-icon{fill:#552222;}#mermaid-svg-LxczHbQPtTrhJNBv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LxczHbQPtTrhJNBv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LxczHbQPtTrhJNBv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LxczHbQPtTrhJNBv .marker.cross{stroke:#333333;}#mermaid-svg-LxczHbQPtTrhJNBv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LxczHbQPtTrhJNBv p{margin:0;}#mermaid-svg-LxczHbQPtTrhJNBv g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-LxczHbQPtTrhJNBv g.classGroup text .title{font-weight:bolder;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster-label text{fill:#333;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster-label span{color:#333;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster-label span p{background-color:transparent;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster text{fill:#333;}#mermaid-svg-LxczHbQPtTrhJNBv .cluster span{color:#333;}#mermaid-svg-LxczHbQPtTrhJNBv .nodeLabel,#mermaid-svg-LxczHbQPtTrhJNBv .edgeLabel{color:#131300;}#mermaid-svg-LxczHbQPtTrhJNBv .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-LxczHbQPtTrhJNBv .label text{fill:#131300;}#mermaid-svg-LxczHbQPtTrhJNBv .labelBkg{background:#ECECFF;}#mermaid-svg-LxczHbQPtTrhJNBv .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-LxczHbQPtTrhJNBv .classTitle{font-weight:bolder;}#mermaid-svg-LxczHbQPtTrhJNBv .node rect,#mermaid-svg-LxczHbQPtTrhJNBv .node circle,#mermaid-svg-LxczHbQPtTrhJNBv .node ellipse,#mermaid-svg-LxczHbQPtTrhJNBv .node polygon,#mermaid-svg-LxczHbQPtTrhJNBv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LxczHbQPtTrhJNBv .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv g.clickable{cursor:pointer;}#mermaid-svg-LxczHbQPtTrhJNBv g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-LxczHbQPtTrhJNBv g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-LxczHbQPtTrhJNBv .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-LxczHbQPtTrhJNBv .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-LxczHbQPtTrhJNBv .dashed-line{stroke-dasharray:3;}#mermaid-svg-LxczHbQPtTrhJNBv .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-LxczHbQPtTrhJNBv #compositionStart,#mermaid-svg-LxczHbQPtTrhJNBv .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #compositionEnd,#mermaid-svg-LxczHbQPtTrhJNBv .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #dependencyStart,#mermaid-svg-LxczHbQPtTrhJNBv .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #dependencyStart,#mermaid-svg-LxczHbQPtTrhJNBv .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #extensionStart,#mermaid-svg-LxczHbQPtTrhJNBv .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #extensionEnd,#mermaid-svg-LxczHbQPtTrhJNBv .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #aggregationStart,#mermaid-svg-LxczHbQPtTrhJNBv .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #aggregationEnd,#mermaid-svg-LxczHbQPtTrhJNBv .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #lollipopStart,#mermaid-svg-LxczHbQPtTrhJNBv .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv #lollipopEnd,#mermaid-svg-LxczHbQPtTrhJNBv .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-LxczHbQPtTrhJNBv .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-LxczHbQPtTrhJNBv .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LxczHbQPtTrhJNBv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LxczHbQPtTrhJNBv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LxczHbQPtTrhJNBv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CustomError
+int code
+string cn_message
+string en_message
+as_dict(detail, lang) : dict
CustomException
+CustomError err
+string detail
+init(err, detail)
<<enumeration>>
ErrorCategories
BASE_ERRORS
BUSINESS_ERRORS
SYSTEM_ERRORS
系统包含三个主要的错误类别:
- 基础错误码 (1000-1999):参数验证、资源访问、权限控制等
- 业务错误码 (2000-2999):具体的业务逻辑错误
- 系统错误码 (9000-9999):系统级异常和未知错误
统一响应中间件
ResponseMiddleware 是异常处理系统的核心组件,负责统一处理所有 API 响应:
日志记录器 业务服务 响应中间件 客户端 日志记录器 业务服务 响应中间件 客户端 #mermaid-svg-96nkzrI708l4Uobk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-96nkzrI708l4Uobk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-96nkzrI708l4Uobk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-96nkzrI708l4Uobk .error-icon{fill:#552222;}#mermaid-svg-96nkzrI708l4Uobk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-96nkzrI708l4Uobk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-96nkzrI708l4Uobk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-96nkzrI708l4Uobk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-96nkzrI708l4Uobk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-96nkzrI708l4Uobk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-96nkzrI708l4Uobk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-96nkzrI708l4Uobk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-96nkzrI708l4Uobk .marker.cross{stroke:#333333;}#mermaid-svg-96nkzrI708l4Uobk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-96nkzrI708l4Uobk p{margin:0;}#mermaid-svg-96nkzrI708l4Uobk .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-96nkzrI708l4Uobk text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-96nkzrI708l4Uobk .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-96nkzrI708l4Uobk .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-96nkzrI708l4Uobk .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-96nkzrI708l4Uobk .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-96nkzrI708l4Uobk #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-96nkzrI708l4Uobk .sequenceNumber{fill:white;}#mermaid-svg-96nkzrI708l4Uobk #sequencenumber{fill:#333;}#mermaid-svg-96nkzrI708l4Uobk #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-96nkzrI708l4Uobk .messageText{fill:#333;stroke:none;}#mermaid-svg-96nkzrI708l4Uobk .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-96nkzrI708l4Uobk .labelText,#mermaid-svg-96nkzrI708l4Uobk .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-96nkzrI708l4Uobk .loopText,#mermaid-svg-96nkzrI708l4Uobk .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-96nkzrI708l4Uobk .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-96nkzrI708l4Uobk .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-96nkzrI708l4Uobk .noteText,#mermaid-svg-96nkzrI708l4Uobk .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-96nkzrI708l4Uobk .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-96nkzrI708l4Uobk .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-96nkzrI708l4Uobk .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-96nkzrI708l4Uobk .actorPopupMenu{position:absolute;}#mermaid-svg-96nkzrI708l4Uobk .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-96nkzrI708l4Uobk .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-96nkzrI708l4Uobk .actor-man circle,#mermaid-svg-96nkzrI708l4Uobk line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-96nkzrI708l4Uobk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 正常响应 自定义异常 通用异常 请求 调用业务逻辑 正常响应 格式化响应 统一格式响应 记录异常信息 标准错误响应 记录错误详情 内部错误响应
桌面客户端异常处理
Electron 桌面客户端实现了多层次的异常处理机制:
#mermaid-svg-ODq6tsnXUjF2gN8C{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ODq6tsnXUjF2gN8C .error-icon{fill:#552222;}#mermaid-svg-ODq6tsnXUjF2gN8C .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ODq6tsnXUjF2gN8C .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ODq6tsnXUjF2gN8C .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ODq6tsnXUjF2gN8C .marker.cross{stroke:#333333;}#mermaid-svg-ODq6tsnXUjF2gN8C svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ODq6tsnXUjF2gN8C p{margin:0;}#mermaid-svg-ODq6tsnXUjF2gN8C .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster-label text{fill:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster-label span{color:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster-label span p{background-color:transparent;}#mermaid-svg-ODq6tsnXUjF2gN8C .label text,#mermaid-svg-ODq6tsnXUjF2gN8C span{fill:#333;color:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C .node rect,#mermaid-svg-ODq6tsnXUjF2gN8C .node circle,#mermaid-svg-ODq6tsnXUjF2gN8C .node ellipse,#mermaid-svg-ODq6tsnXUjF2gN8C .node polygon,#mermaid-svg-ODq6tsnXUjF2gN8C .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ODq6tsnXUjF2gN8C .rough-node .label text,#mermaid-svg-ODq6tsnXUjF2gN8C .node .label text,#mermaid-svg-ODq6tsnXUjF2gN8C .image-shape .label,#mermaid-svg-ODq6tsnXUjF2gN8C .icon-shape .label{text-anchor:middle;}#mermaid-svg-ODq6tsnXUjF2gN8C .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ODq6tsnXUjF2gN8C .rough-node .label,#mermaid-svg-ODq6tsnXUjF2gN8C .node .label,#mermaid-svg-ODq6tsnXUjF2gN8C .image-shape .label,#mermaid-svg-ODq6tsnXUjF2gN8C .icon-shape .label{text-align:center;}#mermaid-svg-ODq6tsnXUjF2gN8C .node.clickable{cursor:pointer;}#mermaid-svg-ODq6tsnXUjF2gN8C .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ODq6tsnXUjF2gN8C .arrowheadPath{fill:#333333;}#mermaid-svg-ODq6tsnXUjF2gN8C .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ODq6tsnXUjF2gN8C .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ODq6tsnXUjF2gN8C .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ODq6tsnXUjF2gN8C .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ODq6tsnXUjF2gN8C .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ODq6tsnXUjF2gN8C .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster text{fill:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C .cluster span{color:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ODq6tsnXUjF2gN8C .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ODq6tsnXUjF2gN8C rect.text{fill:none;stroke-width:0;}#mermaid-svg-ODq6tsnXUjF2gN8C .icon-shape,#mermaid-svg-ODq6tsnXUjF2gN8C .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ODq6tsnXUjF2gN8C .icon-shape p,#mermaid-svg-ODq6tsnXUjF2gN8C .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ODq6tsnXUjF2gN8C .icon-shape .label rect,#mermaid-svg-ODq6tsnXUjF2gN8C .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ODq6tsnXUjF2gN8C .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ODq6tsnXUjF2gN8C .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ODq6tsnXUjF2gN8C :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 权限不足
权限正常
请求失败
请求成功
空间不足
空间充足
应用启动
检查权限
显示权限对话框
继续启动
IPC通信
网络请求
记录错误日志
处理响应数据
文件操作
磁盘空间
显示存储空间警告
执行文件操作
架构概览
异常处理系统采用分层架构设计,确保每个层级都有相应的错误处理机制:
#mermaid-svg-1eq7pJCRrm8r9x0I{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1eq7pJCRrm8r9x0I .error-icon{fill:#552222;}#mermaid-svg-1eq7pJCRrm8r9x0I .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1eq7pJCRrm8r9x0I .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1eq7pJCRrm8r9x0I .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1eq7pJCRrm8r9x0I .marker.cross{stroke:#333333;}#mermaid-svg-1eq7pJCRrm8r9x0I svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1eq7pJCRrm8r9x0I p{margin:0;}#mermaid-svg-1eq7pJCRrm8r9x0I .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster-label text{fill:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster-label span{color:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster-label span p{background-color:transparent;}#mermaid-svg-1eq7pJCRrm8r9x0I .label text,#mermaid-svg-1eq7pJCRrm8r9x0I span{fill:#333;color:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I .node rect,#mermaid-svg-1eq7pJCRrm8r9x0I .node circle,#mermaid-svg-1eq7pJCRrm8r9x0I .node ellipse,#mermaid-svg-1eq7pJCRrm8r9x0I .node polygon,#mermaid-svg-1eq7pJCRrm8r9x0I .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1eq7pJCRrm8r9x0I .rough-node .label text,#mermaid-svg-1eq7pJCRrm8r9x0I .node .label text,#mermaid-svg-1eq7pJCRrm8r9x0I .image-shape .label,#mermaid-svg-1eq7pJCRrm8r9x0I .icon-shape .label{text-anchor:middle;}#mermaid-svg-1eq7pJCRrm8r9x0I .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1eq7pJCRrm8r9x0I .rough-node .label,#mermaid-svg-1eq7pJCRrm8r9x0I .node .label,#mermaid-svg-1eq7pJCRrm8r9x0I .image-shape .label,#mermaid-svg-1eq7pJCRrm8r9x0I .icon-shape .label{text-align:center;}#mermaid-svg-1eq7pJCRrm8r9x0I .node.clickable{cursor:pointer;}#mermaid-svg-1eq7pJCRrm8r9x0I .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1eq7pJCRrm8r9x0I .arrowheadPath{fill:#333333;}#mermaid-svg-1eq7pJCRrm8r9x0I .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1eq7pJCRrm8r9x0I .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1eq7pJCRrm8r9x0I .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1eq7pJCRrm8r9x0I .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1eq7pJCRrm8r9x0I .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1eq7pJCRrm8r9x0I .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster text{fill:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I .cluster span{color:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1eq7pJCRrm8r9x0I .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1eq7pJCRrm8r9x0I rect.text{fill:none;stroke-width:0;}#mermaid-svg-1eq7pJCRrm8r9x0I .icon-shape,#mermaid-svg-1eq7pJCRrm8r9x0I .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1eq7pJCRrm8r9x0I .icon-shape p,#mermaid-svg-1eq7pJCRrm8r9x0I .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1eq7pJCRrm8r9x0I .icon-shape .label rect,#mermaid-svg-1eq7pJCRrm8r9x0I .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1eq7pJCRrm8r9x0I .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1eq7pJCRrm8r9x0I .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1eq7pJCRrm8r9x0I :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 数据层
API 层
用户界面层
异常处理层
自定义异常
日志记录
错误恢复
桌面客户端
Web界面
FastAPI 应用
中间件链
业务服务
文件系统
数据库
外部API
详细组件分析
API 异常处理流程
API 层的异常处理遵循严格的流程:
日志系统 请求处理器 响应中间件 准备中间件 客户端 日志系统 请求处理器 响应中间件 准备中间件 客户端 #mermaid-svg-MJwO0zi9hHycrFFq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MJwO0zi9hHycrFFq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MJwO0zi9hHycrFFq .error-icon{fill:#552222;}#mermaid-svg-MJwO0zi9hHycrFFq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MJwO0zi9hHycrFFq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MJwO0zi9hHycrFFq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MJwO0zi9hHycrFFq .marker.cross{stroke:#333333;}#mermaid-svg-MJwO0zi9hHycrFFq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MJwO0zi9hHycrFFq p{margin:0;}#mermaid-svg-MJwO0zi9hHycrFFq .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MJwO0zi9hHycrFFq text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-MJwO0zi9hHycrFFq .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-MJwO0zi9hHycrFFq .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-MJwO0zi9hHycrFFq .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-MJwO0zi9hHycrFFq .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-MJwO0zi9hHycrFFq #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-MJwO0zi9hHycrFFq .sequenceNumber{fill:white;}#mermaid-svg-MJwO0zi9hHycrFFq #sequencenumber{fill:#333;}#mermaid-svg-MJwO0zi9hHycrFFq #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-MJwO0zi9hHycrFFq .messageText{fill:#333;stroke:none;}#mermaid-svg-MJwO0zi9hHycrFFq .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MJwO0zi9hHycrFFq .labelText,#mermaid-svg-MJwO0zi9hHycrFFq .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-MJwO0zi9hHycrFFq .loopText,#mermaid-svg-MJwO0zi9hHycrFFq .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-MJwO0zi9hHycrFFq .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-MJwO0zi9hHycrFFq .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-MJwO0zi9hHycrFFq .noteText,#mermaid-svg-MJwO0zi9hHycrFFq .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-MJwO0zi9hHycrFFq .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MJwO0zi9hHycrFFq .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MJwO0zi9hHycrFFq .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MJwO0zi9hHycrFFq .actorPopupMenu{position:absolute;}#mermaid-svg-MJwO0zi9hHycrFFq .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-MJwO0zi9hHycrFFq .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MJwO0zi9hHycrFFq .actor-man circle,#mermaid-svg-MJwO0zi9hHycrFFq line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-MJwO0zi9hHycrFFq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 业务逻辑正常 参数验证失败 业务逻辑异常 系统异常 HTTP 请求 转发请求 调用业务逻辑 返回数据 格式化响应 成功响应 抛出自定义异常 记录验证错误 参数验证错误 抛出业务异常 记录业务错误 业务错误响应 抛出系统异常 记录系统错误 内部错误响应
业务服务异常处理
业务服务层实现了针对具体业务场景的异常处理:
草稿创建异常处理
#mermaid-svg-EMp0U2eL6MWcjfqO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EMp0U2eL6MWcjfqO .error-icon{fill:#552222;}#mermaid-svg-EMp0U2eL6MWcjfqO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EMp0U2eL6MWcjfqO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EMp0U2eL6MWcjfqO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EMp0U2eL6MWcjfqO .marker.cross{stroke:#333333;}#mermaid-svg-EMp0U2eL6MWcjfqO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EMp0U2eL6MWcjfqO p{margin:0;}#mermaid-svg-EMp0U2eL6MWcjfqO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster-label text{fill:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster-label span{color:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster-label span p{background-color:transparent;}#mermaid-svg-EMp0U2eL6MWcjfqO .label text,#mermaid-svg-EMp0U2eL6MWcjfqO span{fill:#333;color:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO .node rect,#mermaid-svg-EMp0U2eL6MWcjfqO .node circle,#mermaid-svg-EMp0U2eL6MWcjfqO .node ellipse,#mermaid-svg-EMp0U2eL6MWcjfqO .node polygon,#mermaid-svg-EMp0U2eL6MWcjfqO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EMp0U2eL6MWcjfqO .rough-node .label text,#mermaid-svg-EMp0U2eL6MWcjfqO .node .label text,#mermaid-svg-EMp0U2eL6MWcjfqO .image-shape .label,#mermaid-svg-EMp0U2eL6MWcjfqO .icon-shape .label{text-anchor:middle;}#mermaid-svg-EMp0U2eL6MWcjfqO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EMp0U2eL6MWcjfqO .rough-node .label,#mermaid-svg-EMp0U2eL6MWcjfqO .node .label,#mermaid-svg-EMp0U2eL6MWcjfqO .image-shape .label,#mermaid-svg-EMp0U2eL6MWcjfqO .icon-shape .label{text-align:center;}#mermaid-svg-EMp0U2eL6MWcjfqO .node.clickable{cursor:pointer;}#mermaid-svg-EMp0U2eL6MWcjfqO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EMp0U2eL6MWcjfqO .arrowheadPath{fill:#333333;}#mermaid-svg-EMp0U2eL6MWcjfqO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EMp0U2eL6MWcjfqO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EMp0U2eL6MWcjfqO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EMp0U2eL6MWcjfqO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EMp0U2eL6MWcjfqO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EMp0U2eL6MWcjfqO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster text{fill:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO .cluster span{color:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EMp0U2eL6MWcjfqO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EMp0U2eL6MWcjfqO rect.text{fill:none;stroke-width:0;}#mermaid-svg-EMp0U2eL6MWcjfqO .icon-shape,#mermaid-svg-EMp0U2eL6MWcjfqO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EMp0U2eL6MWcjfqO .icon-shape p,#mermaid-svg-EMp0U2eL6MWcjfqO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EMp0U2eL6MWcjfqO .icon-shape .label rect,#mermaid-svg-EMp0U2eL6MWcjfqO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EMp0U2eL6MWcjfqO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EMp0U2eL6MWcjfqO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EMp0U2eL6MWcjfqO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
否
是
否
是
否
是
创建草稿请求
验证输入参数
参数验证通过?
抛出参数验证异常
复制模板文件
文件复制成功?
抛出草稿创建失败异常
修改草稿配置
配置修改成功?
抛出草稿创建失败异常
保存草稿文件
保存成功?
抛出草稿创建失败异常
更新缓存
返回草稿URL
视频生成异常处理
#mermaid-svg-xQPUTfOqjksVylWp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xQPUTfOqjksVylWp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xQPUTfOqjksVylWp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xQPUTfOqjksVylWp .error-icon{fill:#552222;}#mermaid-svg-xQPUTfOqjksVylWp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xQPUTfOqjksVylWp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xQPUTfOqjksVylWp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xQPUTfOqjksVylWp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xQPUTfOqjksVylWp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xQPUTfOqjksVylWp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xQPUTfOqjksVylWp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xQPUTfOqjksVylWp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xQPUTfOqjksVylWp .marker.cross{stroke:#333333;}#mermaid-svg-xQPUTfOqjksVylWp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xQPUTfOqjksVylWp p{margin:0;}#mermaid-svg-xQPUTfOqjksVylWp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xQPUTfOqjksVylWp .cluster-label text{fill:#333;}#mermaid-svg-xQPUTfOqjksVylWp .cluster-label span{color:#333;}#mermaid-svg-xQPUTfOqjksVylWp .cluster-label span p{background-color:transparent;}#mermaid-svg-xQPUTfOqjksVylWp .label text,#mermaid-svg-xQPUTfOqjksVylWp span{fill:#333;color:#333;}#mermaid-svg-xQPUTfOqjksVylWp .node rect,#mermaid-svg-xQPUTfOqjksVylWp .node circle,#mermaid-svg-xQPUTfOqjksVylWp .node ellipse,#mermaid-svg-xQPUTfOqjksVylWp .node polygon,#mermaid-svg-xQPUTfOqjksVylWp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xQPUTfOqjksVylWp .rough-node .label text,#mermaid-svg-xQPUTfOqjksVylWp .node .label text,#mermaid-svg-xQPUTfOqjksVylWp .image-shape .label,#mermaid-svg-xQPUTfOqjksVylWp .icon-shape .label{text-anchor:middle;}#mermaid-svg-xQPUTfOqjksVylWp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xQPUTfOqjksVylWp .rough-node .label,#mermaid-svg-xQPUTfOqjksVylWp .node .label,#mermaid-svg-xQPUTfOqjksVylWp .image-shape .label,#mermaid-svg-xQPUTfOqjksVylWp .icon-shape .label{text-align:center;}#mermaid-svg-xQPUTfOqjksVylWp .node.clickable{cursor:pointer;}#mermaid-svg-xQPUTfOqjksVylWp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xQPUTfOqjksVylWp .arrowheadPath{fill:#333333;}#mermaid-svg-xQPUTfOqjksVylWp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xQPUTfOqjksVylWp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xQPUTfOqjksVylWp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xQPUTfOqjksVylWp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xQPUTfOqjksVylWp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xQPUTfOqjksVylWp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xQPUTfOqjksVylWp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xQPUTfOqjksVylWp .cluster text{fill:#333;}#mermaid-svg-xQPUTfOqjksVylWp .cluster span{color:#333;}#mermaid-svg-xQPUTfOqjksVylWp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xQPUTfOqjksVylWp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xQPUTfOqjksVylWp rect.text{fill:none;stroke-width:0;}#mermaid-svg-xQPUTfOqjksVylWp .icon-shape,#mermaid-svg-xQPUTfOqjksVylWp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xQPUTfOqjksVylWp .icon-shape p,#mermaid-svg-xQPUTfOqjksVylWp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xQPUTfOqjksVylWp .icon-shape .label rect,#mermaid-svg-xQPUTfOqjksVylWp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xQPUTfOqjksVylWp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xQPUTfOqjksVylWp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xQPUTfOqjksVylWp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
否
是
否
是
视频生成请求
验证API密钥
API密钥有效?
抛出无效API密钥异常
检查用户积分
积分充足?
抛出余额不足异常
验证草稿URL
URL有效?
抛出无效草稿URL异常
提交生成任务
返回任务提交成功
桌面客户端异常处理
桌面客户端实现了多层次的异常处理机制:
IPC 通信异常处理
日志记录器 主进程 预加载脚本 渲染进程 日志记录器 主进程 预加载脚本 渲染进程 #mermaid-svg-t3J8UiDMbJr8E51H{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-t3J8UiDMbJr8E51H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-t3J8UiDMbJr8E51H .error-icon{fill:#552222;}#mermaid-svg-t3J8UiDMbJr8E51H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-t3J8UiDMbJr8E51H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-t3J8UiDMbJr8E51H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-t3J8UiDMbJr8E51H .marker.cross{stroke:#333333;}#mermaid-svg-t3J8UiDMbJr8E51H svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-t3J8UiDMbJr8E51H p{margin:0;}#mermaid-svg-t3J8UiDMbJr8E51H .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-t3J8UiDMbJr8E51H text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-t3J8UiDMbJr8E51H .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-t3J8UiDMbJr8E51H .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-t3J8UiDMbJr8E51H .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-t3J8UiDMbJr8E51H .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-t3J8UiDMbJr8E51H #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-t3J8UiDMbJr8E51H .sequenceNumber{fill:white;}#mermaid-svg-t3J8UiDMbJr8E51H #sequencenumber{fill:#333;}#mermaid-svg-t3J8UiDMbJr8E51H #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-t3J8UiDMbJr8E51H .messageText{fill:#333;stroke:none;}#mermaid-svg-t3J8UiDMbJr8E51H .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-t3J8UiDMbJr8E51H .labelText,#mermaid-svg-t3J8UiDMbJr8E51H .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-t3J8UiDMbJr8E51H .loopText,#mermaid-svg-t3J8UiDMbJr8E51H .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-t3J8UiDMbJr8E51H .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-t3J8UiDMbJr8E51H .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-t3J8UiDMbJr8E51H .noteText,#mermaid-svg-t3J8UiDMbJr8E51H .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-t3J8UiDMbJr8E51H .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-t3J8UiDMbJr8E51H .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-t3J8UiDMbJr8E51H .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-t3J8UiDMbJr8E51H .actorPopupMenu{position:absolute;}#mermaid-svg-t3J8UiDMbJr8E51H .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-t3J8UiDMbJr8E51H .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-t3J8UiDMbJr8E51H .actor-man circle,#mermaid-svg-t3J8UiDMbJr8E51H line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-t3J8UiDMbJr8E51H :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 处理成功 处理失败 调用electronAPI.saveFile() ipcRenderer.invoke('save-file') 处理文件保存 返回保存结果 保存成功 记录错误信息 返回错误信息 显示错误对话框
权限异常处理
桌面客户端特别处理了 macOS 平台的权限问题:
#mermaid-svg-7DnovioOMwk3VU2Y{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7DnovioOMwk3VU2Y .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7DnovioOMwk3VU2Y .error-icon{fill:#552222;}#mermaid-svg-7DnovioOMwk3VU2Y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7DnovioOMwk3VU2Y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7DnovioOMwk3VU2Y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7DnovioOMwk3VU2Y .marker.cross{stroke:#333333;}#mermaid-svg-7DnovioOMwk3VU2Y svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7DnovioOMwk3VU2Y p{margin:0;}#mermaid-svg-7DnovioOMwk3VU2Y .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7DnovioOMwk3VU2Y .cluster-label text{fill:#333;}#mermaid-svg-7DnovioOMwk3VU2Y .cluster-label span{color:#333;}#mermaid-svg-7DnovioOMwk3VU2Y .cluster-label span p{background-color:transparent;}#mermaid-svg-7DnovioOMwk3VU2Y .label text,#mermaid-svg-7DnovioOMwk3VU2Y span{fill:#333;color:#333;}#mermaid-svg-7DnovioOMwk3VU2Y .node rect,#mermaid-svg-7DnovioOMwk3VU2Y .node circle,#mermaid-svg-7DnovioOMwk3VU2Y .node ellipse,#mermaid-svg-7DnovioOMwk3VU2Y .node polygon,#mermaid-svg-7DnovioOMwk3VU2Y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7DnovioOMwk3VU2Y .rough-node .label text,#mermaid-svg-7DnovioOMwk3VU2Y .node .label text,#mermaid-svg-7DnovioOMwk3VU2Y .image-shape .label,#mermaid-svg-7DnovioOMwk3VU2Y .icon-shape .label{text-anchor:middle;}#mermaid-svg-7DnovioOMwk3VU2Y .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7DnovioOMwk3VU2Y .rough-node .label,#mermaid-svg-7DnovioOMwk3VU2Y .node .label,#mermaid-svg-7DnovioOMwk3VU2Y .image-shape .label,#mermaid-svg-7DnovioOMwk3VU2Y .icon-shape .label{text-align:center;}#mermaid-svg-7DnovioOMwk3VU2Y .node.clickable{cursor:pointer;}#mermaid-svg-7DnovioOMwk3VU2Y .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7DnovioOMwk3VU2Y .arrowheadPath{fill:#333333;}#mermaid-svg-7DnovioOMwk3VU2Y .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7DnovioOMwk3VU2Y .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7DnovioOMwk3VU2Y .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7DnovioOMwk3VU2Y .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7DnovioOMwk3VU2Y .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7DnovioOMwk3VU2Y .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7DnovioOMwk3VU2Y .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7DnovioOMwk3VU2Y .cluster text{fill:#333;}#mermaid-svg-7DnovioOMwk3VU2Y .cluster span{color:#333;}#mermaid-svg-7DnovioOMwk3VU2Y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7DnovioOMwk3VU2Y .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7DnovioOMwk3VU2Y rect.text{fill:none;stroke-width:0;}#mermaid-svg-7DnovioOMwk3VU2Y .icon-shape,#mermaid-svg-7DnovioOMwk3VU2Y .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7DnovioOMwk3VU2Y .icon-shape p,#mermaid-svg-7DnovioOMwk3VU2Y .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7DnovioOMwk3VU2Y .icon-shape .label rect,#mermaid-svg-7DnovioOMwk3VU2Y .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7DnovioOMwk3VU2Y .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7DnovioOMwk3VU2Y .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7DnovioOMwk3VU2Y :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 权限不足
是
否
权限正常
应用启动
检查系统权限
权限检查结果
捕获未捕获异常
macOS平台?
显示权限错误对话框
记录错误日志
继续正常启动
用户配置权限
重启应用
工具层异常处理
工具层提供了底层的异常处理能力:
文件下载异常处理
#mermaid-svg-6x6qxOmcZhjChYso{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6x6qxOmcZhjChYso .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6x6qxOmcZhjChYso .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6x6qxOmcZhjChYso .error-icon{fill:#552222;}#mermaid-svg-6x6qxOmcZhjChYso .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6x6qxOmcZhjChYso .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6x6qxOmcZhjChYso .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6x6qxOmcZhjChYso .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6x6qxOmcZhjChYso .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6x6qxOmcZhjChYso .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6x6qxOmcZhjChYso .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6x6qxOmcZhjChYso .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6x6qxOmcZhjChYso .marker.cross{stroke:#333333;}#mermaid-svg-6x6qxOmcZhjChYso svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6x6qxOmcZhjChYso p{margin:0;}#mermaid-svg-6x6qxOmcZhjChYso .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6x6qxOmcZhjChYso .cluster-label text{fill:#333;}#mermaid-svg-6x6qxOmcZhjChYso .cluster-label span{color:#333;}#mermaid-svg-6x6qxOmcZhjChYso .cluster-label span p{background-color:transparent;}#mermaid-svg-6x6qxOmcZhjChYso .label text,#mermaid-svg-6x6qxOmcZhjChYso span{fill:#333;color:#333;}#mermaid-svg-6x6qxOmcZhjChYso .node rect,#mermaid-svg-6x6qxOmcZhjChYso .node circle,#mermaid-svg-6x6qxOmcZhjChYso .node ellipse,#mermaid-svg-6x6qxOmcZhjChYso .node polygon,#mermaid-svg-6x6qxOmcZhjChYso .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6x6qxOmcZhjChYso .rough-node .label text,#mermaid-svg-6x6qxOmcZhjChYso .node .label text,#mermaid-svg-6x6qxOmcZhjChYso .image-shape .label,#mermaid-svg-6x6qxOmcZhjChYso .icon-shape .label{text-anchor:middle;}#mermaid-svg-6x6qxOmcZhjChYso .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6x6qxOmcZhjChYso .rough-node .label,#mermaid-svg-6x6qxOmcZhjChYso .node .label,#mermaid-svg-6x6qxOmcZhjChYso .image-shape .label,#mermaid-svg-6x6qxOmcZhjChYso .icon-shape .label{text-align:center;}#mermaid-svg-6x6qxOmcZhjChYso .node.clickable{cursor:pointer;}#mermaid-svg-6x6qxOmcZhjChYso .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6x6qxOmcZhjChYso .arrowheadPath{fill:#333333;}#mermaid-svg-6x6qxOmcZhjChYso .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6x6qxOmcZhjChYso .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6x6qxOmcZhjChYso .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6x6qxOmcZhjChYso .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6x6qxOmcZhjChYso .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6x6qxOmcZhjChYso .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6x6qxOmcZhjChYso .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6x6qxOmcZhjChYso .cluster text{fill:#333;}#mermaid-svg-6x6qxOmcZhjChYso .cluster span{color:#333;}#mermaid-svg-6x6qxOmcZhjChYso div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6x6qxOmcZhjChYso .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6x6qxOmcZhjChYso rect.text{fill:none;stroke-width:0;}#mermaid-svg-6x6qxOmcZhjChYso .icon-shape,#mermaid-svg-6x6qxOmcZhjChYso .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6x6qxOmcZhjChYso .icon-shape p,#mermaid-svg-6x6qxOmcZhjChYso .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6x6qxOmcZhjChYso .icon-shape .label rect,#mermaid-svg-6x6qxOmcZhjChYso .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6x6qxOmcZhjChYso .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6x6qxOmcZhjChYso .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6x6qxOmcZhjChYso :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
否
是
否
是
否
是
开始下载
解析URL
URL解析成功?
记录解析错误
获取文件列表
获取成功?
记录获取失败
逐个下载文件
下载成功?
记录下载错误
更新文件路径
更新成功?
记录路径更新失败
触发目录扫描
下载完成
依赖关系分析
异常处理系统各组件之间的依赖关系如下:
#mermaid-svg-5Ktq7mAXJH7skjF0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5Ktq7mAXJH7skjF0 .error-icon{fill:#552222;}#mermaid-svg-5Ktq7mAXJH7skjF0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5Ktq7mAXJH7skjF0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .marker.cross{stroke:#333333;}#mermaid-svg-5Ktq7mAXJH7skjF0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5Ktq7mAXJH7skjF0 p{margin:0;}#mermaid-svg-5Ktq7mAXJH7skjF0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster-label text{fill:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster-label span{color:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster-label span p{background-color:transparent;}#mermaid-svg-5Ktq7mAXJH7skjF0 .label text,#mermaid-svg-5Ktq7mAXJH7skjF0 span{fill:#333;color:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .node rect,#mermaid-svg-5Ktq7mAXJH7skjF0 .node circle,#mermaid-svg-5Ktq7mAXJH7skjF0 .node ellipse,#mermaid-svg-5Ktq7mAXJH7skjF0 .node polygon,#mermaid-svg-5Ktq7mAXJH7skjF0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .rough-node .label text,#mermaid-svg-5Ktq7mAXJH7skjF0 .node .label text,#mermaid-svg-5Ktq7mAXJH7skjF0 .image-shape .label,#mermaid-svg-5Ktq7mAXJH7skjF0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-5Ktq7mAXJH7skjF0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .rough-node .label,#mermaid-svg-5Ktq7mAXJH7skjF0 .node .label,#mermaid-svg-5Ktq7mAXJH7skjF0 .image-shape .label,#mermaid-svg-5Ktq7mAXJH7skjF0 .icon-shape .label{text-align:center;}#mermaid-svg-5Ktq7mAXJH7skjF0 .node.clickable{cursor:pointer;}#mermaid-svg-5Ktq7mAXJH7skjF0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .arrowheadPath{fill:#333333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5Ktq7mAXJH7skjF0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5Ktq7mAXJH7skjF0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5Ktq7mAXJH7skjF0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster text{fill:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 .cluster span{color:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5Ktq7mAXJH7skjF0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5Ktq7mAXJH7skjF0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-5Ktq7mAXJH7skjF0 .icon-shape,#mermaid-svg-5Ktq7mAXJH7skjF0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5Ktq7mAXJH7skjF0 .icon-shape p,#mermaid-svg-5Ktq7mAXJH7skjF0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5Ktq7mAXJH7skjF0 .icon-shape .label rect,#mermaid-svg-5Ktq7mAXJH7skjF0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5Ktq7mAXJH7skjF0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5Ktq7mAXJH7skjF0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5Ktq7mAXJH7skjF0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 日志系统
桌面客户端异常处理
API 异常处理
核心异常定义
CustomError
CustomException
ResponseMiddleware
PrepareMiddleware
uncaughtException处理器
IPC异常处理
Python日志记录器
Node.js日志记录器
业务服务
桌面客户端
性能考虑
异常处理系统在设计时充分考虑了性能影响:
异常处理性能优化
- 延迟异常检测:只在必要时进行异常检测,避免不必要的性能开销
- 缓存机制:对频繁使用的错误信息进行缓存,减少重复计算
- 异步处理:使用异步方式处理异常,避免阻塞主线程
- 资源管理:及时释放异常处理过程中的临时资源
日志性能优化
- 异步日志记录:使用异步日志记录器,避免阻塞业务逻辑
- 日志级别控制:根据不同的环境配置适当的日志级别
- 日志轮转:实现日志文件轮转,避免日志文件过大影响性能
故障排除指南
常见异常类型及解决方案
API 异常处理
| 异常类型 | 触发条件 | 解决方案 |
|---|---|---|
| 参数验证失败 | 请求参数不符合验证规则 | 检查请求格式,确保参数类型正确 |
| 资源不存在 | 访问的资源不存在 | 验证资源标识符,确认资源状态 |
| 权限不足 | 用户没有访问权限 | 检查用户权限,重新登录 |
| 认证失败 | 认证信息无效 | 检查认证凭据,重新获取令牌 |
桌面客户端异常处理
| 异常类型 | 触发条件 | 解决方案 |
|---|---|---|
| 权限错误 | 文件访问权限不足 | 在系统偏好设置中授权应用访问 |
| 网络连接失败 | 无法连接到服务器 | 检查网络连接,重试请求 |
| 磁盘空间不足 | 磁盘空间不足 | 清理磁盘空间,释放存储空间 |
| 文件损坏 | 下载的文件损坏 | 重新下载文件,检查文件完整性 |
调试技巧
- 启用详细日志:在开发环境中启用详细的日志记录
- 使用调试工具:利用浏览器开发者工具和 Node.js 调试器
- 单元测试:编写全面的单元测试覆盖异常场景
- 集成测试:进行端到端的集成测试验证异常处理
结论
CapCut Mate 的异常处理系统展现了现代应用程序异常管理的最佳实践。通过分层设计、统一响应格式、多语言支持和优雅降级机制,系统能够在各种异常情况下保持稳定运行。
系统优势
- 一致性:统一的错误响应格式确保了用户体验的一致性
- 可维护性:清晰的异常分类和处理流程便于维护和扩展
- 可观测性:完善的日志记录系统提供了强大的故障诊断能力
- 用户友好:友好的错误提示和恢复机制提升了用户体验
改进建议
- 监控集成:集成专业的错误监控服务,如 Sentry 或类似工具
- 性能监控:添加异常处理的性能指标监控
- 自动化测试:增加更多的异常处理自动化测试用例
- 文档完善:完善异常处理的文档和最佳实践指南
该异常处理系统为 CapCut Mate 提供了坚实的基础,确保了应用程序在面对各种异常情况时都能提供稳定可靠的服务。
文档信息
- 接口文档: docs.jcaigc.cn
- 效果案例: www.jcaigc.cn/workflow
- 开源仓库: https://gitcode.com/gcw_xwJRBZlx/capcut-mate