LoginSignup
4

More than 3 years have passed since last update.

posted at

updated at

Laravel 5.7 + GraphQL(ErrorHandling編)

今回は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

参考リンク

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
What you can do with signing up
4