RFC:HTTP 线路错误
概述
本 RFC 提出了一种标准化方法,用于以一致且结构化的方式处理和表示 HTTP 线路错误。目标是提供清晰且详细的错误响应,以便客户端轻松理解和处理。
错误响应结构
每个错误响应都将遵循具有以下字段的标准化 JSON 结构:
例子
{
    "id": "unique-error-id",
    "http_error_code": {
        "canonical_name": "ERROR_NAME",
        "status": 400
    },
    "message": "short summary of the error",
    "detail": "detailed explanation of the error",
    "data": {
        "additional": "context-specific data"
    },
    "validation": [
        {
            "field": "field_name",
            "value": "invalid_value",
            "reason": "explanation of why the value is invalid"
        }
    ]
}规范错误名称
定义了以下规范错误名称:
错误处理
无效参数
当客户端提供无效参数时,服务器应该响应“INVALID_ARGUMENT”错误。
例子
{
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "http_error_code": {
        "canonical_name": "INVALID_ARGUMENT",
        "status": 400
    },
    "message": "invalid account number provided",
    "detail": "the account number '123456789' does not exist in our records"
}不满足先决条件
当操作由于先决条件不满足而被拒绝时,服务器应该响应“FAILED_PRECONDITION”错误。
例子
{
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "http_error_code": {
        "canonical_name": "FAILED_PRECONDITION",
        "status": 400
    },
    "message": "insufficient funds",
    "detail": "the account '987654321' has insufficient funds for the transaction",
    "data": {
        "current_balance": 50.00,
        "required_balance": 100.00
    }
}未认证
当请求缺少有效的身份验证凭证时,服务器应该响应“UNAUTHENTICATED”错误。
例子
{
    "id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
    "http_error_code": {
        "canonical_name": "UNAUTHENTICATED",
        "status": 401
    },
    "message": "unauthorized access",
    "detail": "the provided credentials are invalid"
}未经授权的访问
由于 JWK 无效。
{
    "id": "b445b036-fd2e-4583-b4cc-61c2b8fb0b73",
    "http_error_code": {
        "canonical_name": "UNAUTHENTICATED",
        "status": 401
    },
    "message": "auth: verify: jwt: unknown kid"
}没有权限
当调用者没有权限执行指定的操作时,服务器应该响应“PERMISSION_DENIED”错误。
例子
{
    "id": "d4e5f6a7-b8c9-0123-def4-567890123456",
    "http_error_code": {
        "canonical_name": "PERMISSION_DENIED",
        "status": 403
    },
    "message": "account locked",
    "detail": "the account '123456789' is locked due to multiple failed login attempts",
    "data": {
        "lock_duration": "24 hours"
    }
}未找到
当找不到请求的资源时,服务器应该响应“NOT_FOUND”错误。
例子
{
    "id": "e5f6a7b8-c9d0-1234-ef56-789012345678",
    "http_error_code": {
        "canonical_name": "NOT_FOUND",
        "status": 404
    },
    "message": "transaction not found",
    "detail": "the transaction with id 'tx1234567890' was not found"
}验证错误
当请求包含无效字段时,服务器应该响应“INVALID_ARGUMENT”错误并包含验证详细信息。
例子
{
    "id": "c30adf71-25c0-4a2b-a1f2-c3ee17efcd17",
    "http_error_code": {
        "canonical_name": "INVALID_ARGUMENT",
        "status": 400
    },
    "message": "validation failure",
    "detail": "fields were invalid",
    "validation": [
        {
            "field": "name",
            "value": "jo",
            "reason": "name must be at least 3 characters long"
        },
        {
            "field": "email",
            "value": "invalid@comcom",
            "reason": "email must be a valid email address"
        }
    ]
}内部服务器错误
当处理请求时发生意外错误时,服务器应该以“内部”错误进行响应。
{
    "id": "f6a7b8c9-d0e1-2345-f678-901234567890",
    "http_error_code": {
        "canonical_name": "INTERNAL",
        "status": 500
    },
    "message": "server error",
    "detail": "an unexpected error occurred while processing the request"
}嵌套数据的复杂误差
当错误涉及多个嵌套错误时,服务器应该为错误消息的每个部分提供详细的上下文。
例子
{
    "id": "9f8b7c6d-4e5f-4a2b-8c3d-1e2f3a4b5c6d",
    "http_error_code": {
        "canonical_name": "FAILED_PRECONDITION",
        "status": 400
    },
    "message": "transaction failed: insufficient funds: daily withdrawal limit exceeded",
    "data": [
        {
            "message": "transaction failed",
            "data": {
                "transaction_id": "tx1234567890",
                "amount": 150.00,
                "currency": "USD"
            }
        },
        {
            "message": "insufficient funds",
            "data": {
                "account_id": "acc987654321",
                "current_balance": 50.00,
                "required_balance": 150.00
            }
        },
        {
            "message": "daily withdrawal limit exceeded",
            "data": {
                "account_id": "acc987654321",
                "daily_limit": 1000.00,
                "amount_attempted": 1500.00
            }
        }
    ]
}在此示例中,错误消息由三部分组成:
错误消息的每个部分都有自己的数据部分,为错误的每个部分提供详细的上下文。这种结构使客户端能够了解与错误消息的每个部分相关的具体上下文和数据,从而更轻松地调试和解决问题。
问题详细信息
问题详细信息 RFC 是一种用于表示 HTTP API 中的错误的标准化格式。它定义了一种结构化的方式,以机器可读的格式提供有关错误的详细信息,使客户端更容易理解和有效地处理错误。
例子
{
    "status": 400,
    "title": "Insufficient Funds",
    "detail": "The account '987654321' has insufficient funds for the transaction.",
    "type": "https://example.com/probs/insufficient-funds",
    "instance": "/accounts/12345/transactions/67890",
    "extra_custom_key": "current_balance",
    "extra_custom_value": 50.00,
    "extra_custom_key2": "required_balance",
    "extra_custom_value2": 100.00
}HTTP 线路错误和问题详情之间的差异
虽然 HTTP 线路错误和问题详细信息都提供了一种结构化的方式来表示 HTTP API 中的错误,但仍存在一些主要区别:
问题细节缺失了什么
问题详细信息 (RFC 7807) 提供了表示错误的标准化格式,但它们缺少 HTTP Wire Errors 解决的一些功能:
HTTP 线路错误如何提供解决方案
HTTP Wire Errors 通过以下方式解决这些限制:
作者
Gerasimos Maropoulos 是 Iris Web 框架的作者,该框架是 Go 编程语言的一款高效且功能丰富的 Web 框架。他在编程社区中因其对 Web 开发的贡献和对 Go 语言的专业知识而闻名。Gerasimos 撰写了大量在线文章和教程,帮助开发人员了解和利用 Go 的强大功能来构建可扩展且高性能的 Web 应用程序。他在 Iris 上的工作使其成为 Go 生态系统中最受欢迎的 Web 框架之一,以其简单、快速和广泛的功能集而闻名。
Gerasimos 编写此 RFC 是为了满足对处理和表示 HTTP 线路错误的标准化方法的需求。通过为错误响应提供清晰一致的结构,他的目标是让开发人员更容易调试和了解其应用程序中的错误上下文。此 RFC 是他不断努力改善开发人员体验并确保使用 Iris 构建的应用程序稳健且可维护的一部分。
结论
此 RFC 定义了处理和表示 HTTP 线路错误的标准化方法。通过遵循此结构,开发人员可以确保一致且清晰的错误响应,从而使客户端更容易理解和有效处理错误。