Files
mr.koi 454e6c51d7 Release 0.2.0
Complete OpenAPI 3.0/3.1 generation, diagnostics, lifecycle safety, enum and naming mappings, bilingual documentation, examples, and pub.dev release validation.
2026-07-31 16:47:39 +08:00

151 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 诊断
[English](../DIAGNOSTICS.md) | [简体中文](DIAGNOSTICS.md)
配置、加载、解析、渲染和生命周期问题统一表示为 `KoiDiagnostic`:
```dart
class KoiDiagnostic {
final String code;
final DiagnosticSeverity severity; // info | warning | error
final String message;
final String? source;
final String? location;
}
```
`code` 是稳定的机器可读标识;message 文案可能随版本改进。`source` 表示配置
路径、文档 URL/文件或生成文件;`location` 通常是 source 内的 JSONPath、
JSON Pointer 或其他逻辑位置。
## Severity 行为
- `info`:正常决策,例如跳过未变化的生成;
- `warning`:输出仍然可靠,但发生改名、安全降级或明确省略的非阻塞能力;
- `error`:继续执行可能产生无效客户端,生成器抛出
`KoiDiagnosticException`。
CLI 默认输出 warning/error;`--verbose` 还会输出 info 和失败堆栈。
library 调用方可检查诊断:
```dart
try {
final result = await const KoiSwaggerParser().generate();
for (final item in result.diagnostics) {
print(item.format());
}
} on KoiDiagnosticException catch (error) {
for (final item in error.diagnostics) {
print(item.format());
}
}
```
自动化应匹配 `code`,不要匹配 message 文本。需要区分上下文时再断言 `source`
或 `location`。
## 常见 code
### 配置
| Code | 含义和处理 |
|---|---|
| `config.missing_sources` | 添加至少一个启用的 `input.swagger_urls`。 |
| `config.unknown_key` | 修正拼写或删除当前版本不认识的字段;warning。 |
| `config.invalid_section` | 把 scalar/list 改成预期 YAML map。 |
| `config.invalid_string` / `config.invalid_boolean` | 修正 YAML scalar 类型。 |
| `config.invalid_string_list` | include/exclude filter 必须是字符串列表。 |
| `config.invalid_filter_regex` | 修正 `regex:` 后的 Dart 表达式。 |
| `config.no_outputs_enabled` | API/model 不能同时关闭。 |
| `config.api_requires_models` | 当前 API renderer 依赖生成 model。 |
| `config.unsupported_api_renderer` | 保持 `use_retrofit: true`;目前没有其他公开 API renderer。 |
| `config.external_wrapper_import_required` | 添加 `external_generic.import`。 |
| `config.mapping_target_collision` | 为 mapping source 设置不同的 Dart 目标名。 |
| `config.import_mapping_conflict` | 同一映射 Dart 类型只能使用一个 import。 |
| `config.conflicting_schema_mapping` | 同一 schema 不能既重命名又由外部类型替换。 |
| `config.ambiguous_enum_mapping` | 使用类型明确、无歧义的 enum wire value。 |
### 文档与引用
| Code | 含义和处理 |
|---|---|
| `openapi.missing_version` / `openapi.unsupported_version` | 提供 OpenAPI 3.0.x/3.1.x 文档。 |
| `openapi.invalid_info` / `openapi.invalid_paths` | 修正文档对应关键结构。 |
| `openapi.source_load_failed` / `openapi.source_http_error` | 检查文件路径、URL、访问权限和响应状态。 |
| `openapi.unresolved_ref` | 本地 JSON Pointer 不存在。 |
| `openapi.unresolved_external_ref` | 外部资源/fragment 不存在或无法加载。 |
| `openapi.external_ref_not_bundled` | ref 归一化失败;检查前序 source/resolver 诊断。 |
| `openapi.external_component_renamed` | 外部 component 冲突已确定性改名;warning。 |
| `openapi.multisource_component_renamed` | root 间 component 冲突已确定性改名;warning。 |
| `openapi.multisource_operation_conflict` | 两个 root 定义相同 method/path;删除或拆分其中一个。 |
| `openapi.callbacks_not_supported` / `openapi.webhooks_not_supported` | 不生成反向调用 client;warning。 |
| `openapi.links_not_supported` | 不生成 Link Object 调用关系;warning。 |
### Parameter、request 与 response
| Code | 含义和处理 |
|---|---|
| `openapi.invalid_parameter_style` | 使用与 parameter location 匹配的 style。 |
| `openapi.deep_object_requires_object` | deepObject parameter 必须使用 object schema。 |
| `openapi.delimited_parameter_requires_array` | space/pipe-delimited parameter 必须使用 array schema。 |
| `openapi.parameter_content_count` | Parameter Object `content` 必须恰有一个 media type。 |
| `openapi.request_body_schema_missing` | 为选中的 request media type 添加 schema。 |
| `openapi.unsupported_request_content_type` | 使用已支持 request codec 或手写 endpoint。 |
| `openapi.unsupported_response_content_type` | 使用已支持 response codec 或手写 endpoint。 |
| `openapi.success_response_missing` | 添加显式 2xx response;`default` 不是 success。 |
| `openapi.multiple_success_response_types` | 多个成功 JSON body type 统一为 `Object?`;warning。 |
| `openapi.mixed_success_media_types` | 单个生成方法无法安全 decode binary/stream + JSON success。 |
| `openapi.path_parameter_forced_required` | 声明为 optional 的 path parameter 被强制为 required;warning。 |
### Schema 与命名
| Code | 含义和处理 |
|---|---|
| `openapi.property_read_write_only` | property 不能同时 read-only/write-only。 |
| `openapi.invalid_additional_properties` | 使用 boolean 或 Schema Object。 |
| `openapi.property_name_collision` | 自动 suffix 避免了 Dart field collision;warning。 |
| `openapi.operation_name_collision` | 自动 suffix 避免了 method collision;warning。 |
| `openapi.operation_argument_name_collision` | parameter 与 body、cancel token 或其他参数冲突。 |
| `openapi.duplicate_enum_member_name` | 多个 wire value 映射到同名,已添加 suffix。 |
| `openapi.enum_member_name_sanitized` | enum member name 已转换为合法 Dart identifier。 |
| `filter.required_model_excluded` | 选中 API 依赖被排除 model;包含该 model 或排除调用方。 |
| `filter.model_pattern_unmatched` | `included_models` pattern 没有匹配 schema。 |
### Server 与 security
| Code | 含义和处理 |
|---|---|
| `openapi.server_url_missing` | 添加非空 server URL。 |
| `openapi.server_variable_default_missing` | 为每个 server variable 提供 default。 |
| `openapi.server_variable_default_invalid` | 让 default 属于声明的 enum value。 |
| `openapi.server_variable_unresolved` | 定义 server URL 中的每个 variable。 |
| `openapi.unknown_security_scheme` | 在 components 中定义被引用 scheme。 |
| `openapi.unsupported_security_scheme` | scheme 只在文档边界内保留或被拒绝。 |
| `openapi.http_auth_requires_custom_interceptor` | 在宿主 Dio 层实现凭证注入;warning。 |
### 生成生命周期
| Code | 含义和处理 |
|---|---|
| `lifecycle.unchanged_skipped` | hash/file 一致,已安全跳过生成。 |
| `lifecycle.manifest_invalid` | 旧 manifest 损坏;重建输出但不信任其删除列表。 |
| `lifecycle.manifest_version_ignored` | manifest schema 不兼容,其删除列表被忽略。 |
| `lifecycle.output_outside_managed_roots` | renderer 输出越过 API/model 根,已拒绝。 |
| `lifecycle.duplicate_output_path` | 两个渲染文件以不同内容指向同一路径。 |
| `lifecycle.stale_path_outside_roots` | 旧路径位于当前 root 外,因此保留。 |
| `lifecycle.stale_file_modified` | stale 生成文件已被编辑,保留供人工处理。 |
| `lifecycle.generated_file_missing` | 主生成文件在 fix/format/build 期间消失。 |
| `lifecycle.control_file_not_stale` | lifecycle 控制文件永不作为 stale 输出处理。 |
## 设计原则
1. unresolved ref、非法 wire style 和不支持 codec 不会静默变成 `dynamic`;
2. 安全且可编译的自动改名可以 warning 后继续;
3. 不会破坏其他输出的不支持结构会 warning 后明确省略;
4. stale cleanup 在 path containment 或 hash ownership 不确定时保留文件;
5. 可用时诊断会带 component、operation、parameter 或文件上下文。
minor release 可以增加新 code。自动化应把未知 warning 视为需复核,把未知 error
视为阻塞。