• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

overblog / GraphQLBundle / 24230000246

10 Apr 2026 06:35AM UTC coverage: 98.481% (-0.07%) from 98.546%
24230000246

Pull #1243

github

web-flow
Merge 07076ede9 into 7e9f36ef2
Pull Request #1243: fix: only load profiler services when Symfony profiler is available

1 of 2 new or added lines in 1 file covered. (50.0%)

2 existing lines in 1 file now uncovered.

4539 of 4609 relevant lines covered (98.48%)

74.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.14
/src/DataCollector/GraphQLCollector.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Overblog\GraphQLBundle\DataCollector;
6

7
use GraphQL\Error\SyntaxError;
8
use GraphQL\Language\AST\DocumentNode;
9
use GraphQL\Language\AST\FieldNode;
10
use GraphQL\Language\AST\OperationDefinitionNode;
11
use GraphQL\Language\Parser;
12
use Overblog\GraphQLBundle\Event\ExecutorResultEvent;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
16
use Throwable;
17

18
use function count;
19
use function microtime;
20

21
final class GraphQLCollector extends DataCollector
22
{
23
    /**
24
     * GraphQL Batches executed.
25
     */
26
    protected array $batches = [];
27

28
    public function collect(Request $request, Response $response, ?Throwable $exception = null): void
29
    {
30
        $error = false;
2✔
31
        $count = 0;
2✔
32
        $schema = null;
2✔
33
        foreach ($this->batches as $batch) {
2✔
34
            if (!$schema) {
2✔
35
                $schema = $batch['schema'];
2✔
36
            }
37
            if (isset($batch['error'])) {
2✔
38
                $error = true;
2✔
39
            }
40
            $count += $batch['count'];
2✔
41
        }
42

43
        $this->data = [
2✔
44
            'schema' => $schema,
2✔
45
            'batches' => $this->batches,
2✔
46
            'count' => $count,
2✔
47
            'error' => $error,
2✔
48
        ];
2✔
49
    }
50

51
    /**
52
     * Check if we have an error.
53
     */
54
    public function getError(): bool
55
    {
56
        return $this->data['error'] ?? false;
2✔
57
    }
58

59
    /**
60
     * Count the number of executed queries.
61
     */
62
    public function getCount(): int
63
    {
64
        return $this->data['count'] ?? 0;
2✔
65
    }
66

67
    /**
68
     * Return the targeted schema.
69
     */
70
    public function getSchema(): ?string
71
    {
72
        return $this->data['schema'];
2✔
73
    }
74

75
    /**
76
     * Return the list of executed batch.
77
     */
78
    public function getBatches(): array
79
    {
80
        return $this->data['batches'] ?? [];
2✔
81
    }
82

83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function reset(): void
87
    {
UNCOV
88
        $this->data = [];
×
89
    }
90

91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function getName(): string
95
    {
96
        return 'graphql';
2✔
97
    }
98

99
    /**
100
     * Hook into the GraphQL events to populate the collector.
101
     */
102
    public function onPostExecutor(ExecutorResultEvent $event): void
103
    {
104
        $executorArgument = $event->getExecutorArguments();
2✔
105
        $queryString = $executorArgument->getRequestString();
2✔
106
        $operationName = $executorArgument->getOperationName();
2✔
107
        $variables = $executorArgument->getVariableValue();
2✔
108
        $queryTime = microtime(true) - $executorArgument->getStartTime();
2✔
109

110
        $result = $event->getResult()->toArray();
2✔
111

112
        $batch = [
2✔
113
            'schema' => $executorArgument->getSchemaName(),
2✔
114
            'queryString' => $queryString,
2✔
115
            'queryTime' => $queryTime,
2✔
116
            'variables' => $this->cloneVar($variables),
2✔
117
            'result' => $this->cloneVar($result),
2✔
118
            'count' => 0,
2✔
119
        ];
2✔
120

121
        try {
122
            $parsed = Parser::parse($queryString);
2✔
123
            $batch['graphql'] = $this->extractGraphql($parsed, $operationName);
2✔
124
            if (isset($batch['graphql']['fields'])) {
2✔
125
                $batch['count'] += count($batch['graphql']['fields']);
2✔
126
            }
127
            $error = $result['errors'][0] ?? false;
2✔
128
            if ($error) {
2✔
129
                $batch['error'] = [
2✔
130
                    'message' => $error['message'],
2✔
131
                    'location' => $error['locations'][0] ?? false,
2✔
132
                ];
2✔
133
            }
134
        } catch (SyntaxError $error) {
2✔
135
            $location = $error->getLocations()[0] ?? false;
2✔
136
            $batch['error'] = ['message' => $error->getMessage(), 'location' => $location];
2✔
137
        }
138

139
        $this->batches[] = $batch;
2✔
140
    }
141

142
    /**
143
     * Extract GraphQL Information from the documentNode.
144
     */
145
    protected function extractGraphql(DocumentNode $document, ?string $operationName): array
146
    {
147
        $operation = null;
2✔
148
        $fields = [];
2✔
149

150
        foreach ($document->definitions as $definition) {
2✔
151
            if ($definition instanceof OperationDefinitionNode) {
2✔
152
                $definitionOperation = $definition->name->value ?? null;
2✔
153
                if ($operationName != $definitionOperation) {
2✔
UNCOV
154
                    continue;
×
155
                }
156

157
                $operation = $definition->operation;
2✔
158
                foreach ($definition->selectionSet->selections as $selection) {
2✔
159
                    if ($selection instanceof FieldNode) {
2✔
160
                        $name = $selection->name->value;
2✔
161
                        $alias = $selection->alias ? $selection->alias->value : null;
2✔
162

163
                        $fields[] = [
2✔
164
                            'name' => $name,
2✔
165
                            'alias' => $alias,
2✔
166
                        ];
2✔
167
                    }
168
                }
169
            }
170
        }
171

172
        return [
2✔
173
            'operation' => $operation,
2✔
174
            'operationName' => $operationName,
2✔
175
            'fields' => $fields,
2✔
176
        ];
2✔
177
    }
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc