Laravel与GraphQL有个约会(二)-GraphQL自定义异常处理

场景介绍:

    Laravel中使用folklore/graphql方案解决GraphQL API。请求GraphQL API,如果内部出现异常,是不会被Laravel自带的异常处理器捕获的。需求是:我想通过Bugsnag获取异常信息,但是在Laravel自带的异常体系中捕获不到。GraphQL没有特别详细的文档介绍,所以只好看框架源代码来寻找解决方法了。分析流程如下:

Clipboard Image.png

为什么会出现异常捕获不到的原因呢?

上一节我们提到GraphQL中核心的执行逻辑都在\Folklore\GraphQLGraphQLController的executeQuery()方法中执行。我们先来看下该方法的执行流程:

在executeQuery()方法中核心逻辑在最后的返回值部分,通过app()方法拿到ServiceProvider中注册的graphql对象执行query()方法。之前都只是一些参数准备。如$query参数拿到mutation或query的请求json。$variables拿到GraphQL传入参数,通过$schema定义的规则去解析请求,如果不传就使用配置文件中的默认配置项。

此处进入query()方法,该方法的路径是Folklore\GraphQL\GraphQL

Clipboard Image.png

query()的if判断是不是很熟悉,我们平时返回查询结果都是这种模板。query()中的又继续调用了queryAndReturnResult()方法。queryAndReturnResult()中之前也是在做一些参数准备:$defaultFieldResolver保存了GraphQL字段解析器,$root:获取GraphQL查询树的根节点。下面我们进入GraphQLBase::executeQuery()方法.

该代码位于webony项目源代码的根路径下:

Clipboard Image.png

上面的代码验证了我之前在上一篇博客中提的:folklore/graphql项目就是在webonyx/graphql-php项目的基础上实现的。此处使用了设计模式中的委托模式。前端兄弟应该不会陌生。最近在学习IOS与React-Native混合开发中有存在这种处理机制,无处不在,不经感慨,基础真的是编程的内功。设计作为编程的一门基础,在框架中体现的淋漓尽致。回到正题:委托模式主要解决了异步编程。此处不详细描述,借用该框架PromiseAdapter 接口的一段描述Provides a means for integration of async PHP platforms (related docs) 大致意思是说提供了异步编程。此处采用异步编程,应该是不想阻塞,PHP主线程的执行。ok,我们进入promiseToExcute()方法。

promiseToExcute()方法也在当前类下:

Clipboard Image.png

此处捕获了GraphQL中的异常,这也是为什么Laravel中的异常机制捕获不到GraphQL中异常的原因。try-catch体重主要做了一些参数的校验,查询操作。大家有兴趣可以继续往下面看。

既然流程已经分析清楚了,那么我们来分析解决方案:

我们再次回到Folkore\GraphQL\GraphQL中来:

Clipboard Image.png

如果出现查询错误会执行上图中标红的代码。首先会去获取配置文件中获取errorformatter参数,通过该参数获取异常的处理方法(注意下面arraymap()函数,实际上在调用异常处理函数)。

所以我们可以通过配置config/graphql.php中的error_formatter参数项来决定异常的处理函数Clipboard Image.png

默认的错误处理函数如下:

Clipboard Image.png

参考默认的错误处理函数,我们自己定义一个自定义的异常处理方法。

有了上面的铺垫我们可以开始着手写代码了:

异常类处理类如下

Clipboard Image.png

在该类中我加入了Bugsag。还有不足的地方是,项目没有自定义异常,一些错误异常提示直接通过对象Exception抛出,这种也会进入BugSag处理流程。感觉太浪费资源了。后面可以改进一下,自定义一些异常,然后将这些自定义异常过滤掉,减少Bugsnag资源消耗。

日记本

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

赞赏支持
被以下专题收入,发现更多相似内容