Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Typed Errors and Graphene

未关闭
#1,427 10 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
25/100
Issue 类型
功能
描述清晰度
需要澄清
活跃度
停滞
技术栈
graphql, python
领域
api, backend

调研方向

没有指定任何仓库文件、测试或入口点。首先查看 issue 中提出的 ErrorInterface、error union 和 mutation shape,然后与维护者确认这应该被记录为文档还是实现,以及哪些验收标准可以定义完成。

由索引模型根据 Issue 内容生成。

描述

✨ enhancement

Hi folks,

I'm raising this issue to gauge ideas from the Python community on error handling best practices.

The usual way to handle errors in GraphQL is by inspecting the top-level errors key:

{
  "errors": {
    # ... your error details ...
  },
  "data": null
}

However, this is usually problematic for API clients as they don't know what to expect from this errors key.
This means that error discoverability is impacted.

Another downside, is that the data key must be null when these high-level errors are raised.
In many situations API clients are interested in calling a mutation and, even if it fails, they'd like to receive data back. This data can be anything, but it's usually the object being mutated itself.

Another approach is extending upon this idea of typed errors that is strongly supported by Lee Byron as you can see here.

This seems to solve both problems above (along with many others). Here's my take on what this would look like in Graphene:

class ErrorInterface(graphene.Interface):
    message = graphene.NonNull(graphene.String)


class ThingAErrorType(graphene.ObjectType):
    class Meta:
        interfaces = [ErrorInterface]


class ThingBErrorType(graphene.ObjectType):
    class Meta:
        interfaces = [ErrorInterface]


class MySweetMutationErrorUnion(graphene.Union):
    class Meta:
        types = [ThingAErrorType, ThingBErrorType]


class MySweetMutation():
    error = graphene.Field(MySweetMutationErrorUnion)
    output = graphene.Field(MySweetOutputType)

    def mutate(self, info, input):
        try:
             thing_a = do_thing_a(input)
        except ThingAException:
             return MySweetMutation(error=ThingAErrorType())
        try:
             thing_b = do_thing_b(input)
        except ThingBException:
             return MySweetMutation(error=ThingBErrorType())
        # happy path!
        output = MySweetOutputType(thing_a=thing_a, thing_b=thing_b)
        return MySweetMutation(output=output)

If we have a look at what the schema looks like, we have this:

image

image

And finally, API clients can query this mutation like this:

    mutation mySweetMutation($input: MySweetMutationInput!) {
        mySweetMutation(input: $input) {
            output {
                # ....
            }
            error {
                ... on ThingAError {
                    __typename
                    message
                }
                ... on ThingBError {
                    __typename
                    message
                }
                 # We have an interface here so that we
                 # can extend the union with more errors without breaking
                 # backwards compatibility!!
                 __typename
                 message
            }
        }
    }

I'm interested in your thoughts in this approach.
Thanks!

主要语言
Python
星标
8.2k
派生
818
PR 合并指标
30 天内没有已合并 PR

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

graphql-python/graphene 的其他 Issue

查看 graphql-python/graphene 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。