LoginSignup
12
4

More than 5 years have passed since last update.

Laravel 5.7 + GraphQL(ErrorHandling編)

Last updated at Posted at 2018-10-23

今回はLaravel5.7+GraphQLでエラーハンドリングについての記事です。
GraphQL実行時に例外発生した際にエラーメッセージをログに出力してくれなかったのでその対処法を残します。

シリーズ記事

例外を発生させてみる

GraphQLの特徴なのですが、
例外が発生した場合も 200 レスポンスが返り errors.messages に例外メッセージが出力されます。

app/GraphQL/Query/PostQuery.php

    public function resolve($root, $args, $context, ResolveInfo $info) : Post
    {
        throw new \Exception('test error');

        $query = Post::query();

        if (isset($args['id'])) {
            $query->where('id', $args['id']);
        }

        return $query->first();
    }

スクリーンショット 2018-10-23 17.04.53.png

ここまではOKなのですが、
何と発生した例外メッセージがログファイルに出力されません...😭

GraphQL例外時に実行される関数

config/graphql.php

    'error_formatter' => [\Folklore\GraphQL\GraphQL::class, 'formatError'],

Folklore\GraphQL\GraphQLformatError 関数が実行されます。
https://github.com/Folkloreatelier/laravel-graphql/blob/develop/src/Folklore/GraphQL/GraphQL.php#L287-L306

    public static function formatError(Error $e)
    {
        $error = [
            'message' => $e->getMessage()
        ];

        $locations = $e->getLocations();
        if (!empty($locations)) {
            $error['locations'] = array_map(function ($loc) {
                return $loc->toArray();
            }, $locations);
        }

        $previous = $e->getPrevious();
        if ($previous && $previous instanceof ValidationError) {
            $error['validation'] = $previous->getValidatorMessages();
        }

        return $error;
    }

ログ出力してないですね💦
App\Exceptions\Handlerreport 関数も通らないので注意です。

暫定対応

$ php artisan make:exception GraphQLException

src/app/Exceptions/GraphQLException.php

<?php

declare(strict_types = 1);

namespace App\Exceptions;

use Folklore\GraphQL\GraphQL;
use Folklore\GraphQL\Error\ValidationError;
use GraphQL\Error\Error;

class GraphQLException extends GraphQL
{
    public static function formatError(Error $e)
    {
        $error = parent::formatError($e);

        // Logging
        logger()->error($error);
        logger()->error(request()->all());
        logger()->error($e);

        return $error;
    }
}

レスポンス、リクエスト、例外情報をログに出力する処理を追加します。
あんまり推奨されるやり方ではない気がしますが、とりあえずログ出力できることを確認しました。
もっと良いやり方があればコメントで教えてください😊

config/graphql.php

    'error_formatter' => [App\Exceptions\GraphQLException::class, 'formatError'],

storage/logs/laravel.log

[2018-10-23 08:03:08] local.ERROR: array (
  'message' => 'test error',
  'locations' => 
  array (
    0 => 
    array (
      'line' => 2,
      'column' => 3,
    ),
  ),
)  
[2018-10-23 08:03:08] local.ERROR: array (
  'query' => '{
  post {
    id
    title
  }
}',
  'variables' => NULL,
  'operationName' => NULL,
)  
[2018-10-23 08:03:08] local.ERROR: Exception: test error in /Users/ucan/study/practice-laravel-graphql/app/GraphQL/Query/PostQuery.php:63
Stack trace:

graphiql

スクリーンショット 2018-10-23 17.04.53.png

参考リンク

12
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
4