Skip to content

Commit ef869b5

Browse files
committed
CR
1 parent a3ec9e6 commit ef869b5

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sentry\Laravel\Tracing\Integrations;
4+
5+
interface IntegrationInterface
6+
{
7+
public static function supported(): bool;
8+
}

src/Sentry/Laravel/Tracing/Integrations/LighthouseIntegration.php

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
namespace Sentry\Laravel\Tracing\Integrations;
44

5+
use GraphQL\Language\AST\DocumentNode;
56
use GraphQL\Language\AST\OperationDefinitionNode;
6-
use Illuminate\Contracts\Events\Dispatcher;
7+
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
78
use Nuwave\Lighthouse\Events\EndExecution;
89
use Nuwave\Lighthouse\Events\EndRequest;
910
use Nuwave\Lighthouse\Events\StartExecution;
@@ -12,9 +13,9 @@
1213
use Sentry\SentrySdk;
1314
use Sentry\Tracing\SpanContext;
1415

15-
class LighthouseIntegration
16+
class LighthouseIntegration implements IntegrationInterface
1617
{
17-
/** @var array<int, <string|null, \GraphQL\Language\AST\OperationDefinitionNode>> $operations */
18+
/** @var array<int, array{?string, \GraphQL\Language\AST\OperationDefinitionNode}> $operations */
1819
private $operations;
1920

2021
/** @var \Sentry\Tracing\Span|null $previousSpan */
@@ -26,16 +27,12 @@ class LighthouseIntegration
2627
/** @var \Sentry\Tracing\Span|null $operationSpan */
2728
private $operationSpan;
2829

29-
public function __construct(Dispatcher $evenDispatcher)
30+
public function __construct(EventDispatcher $eventDispatcher)
3031
{
31-
if (!class_exists(StartRequest::class)) {
32-
return;
33-
}
34-
35-
$evenDispatcher->listen(StartRequest::class, [$this, 'handleStartRequest']);
36-
$evenDispatcher->listen(StartExecution::class, [$this, 'handleStartExecution']);
37-
$evenDispatcher->listen(EndExecution::class, [$this, 'handleEndExecution']);
38-
$evenDispatcher->listen(EndRequest::class, [$this, 'handleEndRequest']);
32+
$eventDispatcher->listen(StartRequest::class, [$this, 'handleStartRequest']);
33+
$eventDispatcher->listen(StartExecution::class, [$this, 'handleStartExecution']);
34+
$eventDispatcher->listen(EndExecution::class, [$this, 'handleEndExecution']);
35+
$eventDispatcher->listen(EndRequest::class, [$this, 'handleEndRequest']);
3936
}
4037

4138
public function handleStartRequest(StartRequest $startRequest): void
@@ -46,12 +43,12 @@ public function handleStartRequest(StartRequest $startRequest): void
4643
return;
4744
}
4845

49-
$this->operations = [];
50-
5146
$context = new SpanContext;
5247
$context->setOp('graphql.request');
5348

54-
$this->requestSpan = $this->previousSpan->startChild($context);
49+
$this->operations = [];
50+
$this->requestSpan = $this->previousSpan->startChild($context);
51+
$this->operationSpan = null;
5552

5653
SentrySdk::getCurrentHub()->setSpan($this->requestSpan);
5754
}
@@ -62,14 +59,18 @@ public function handleStartExecution(StartExecution $startExecution): void
6259
return;
6360
}
6461

62+
if (!$startExecution->query instanceof DocumentNode) {
63+
return;
64+
}
65+
6566
/** @var \GraphQL\Language\AST\OperationDefinitionNode|null $operationDefinition */
6667
$operationDefinition = $startExecution->query->definitions[0] ?? null;
6768

68-
if ($operationDefinition === null) {
69+
if (!$operationDefinition instanceof OperationDefinitionNode) {
6970
return;
7071
}
7172

72-
$this->operations[] = [$startExecution->operationName, $operationDefinition];
73+
$this->operations[] = [$startExecution->operationName ?? null, $operationDefinition];
7374

7475
$context = new SpanContext;
7576
$context->setOp(
@@ -147,6 +148,9 @@ private function updateTransaction(): void
147148
SentrySdk::getCurrentHub()->getTransaction()->setName($transactionName);
148149
}
149150

151+
/**
152+
* @return array<int, string>
153+
*/
150154
private function extractOperationNames(OperationDefinitionNode $operation): array
151155
{
152156
if ($operation->name !== null) {
@@ -157,9 +161,9 @@ private function extractOperationNames(OperationDefinitionNode $operation): arra
157161

158162
/** @var \GraphQL\Language\AST\FieldNode $selection */
159163
foreach ($operation->selectionSet->selections as $selection) {
160-
$selectionSet[] = $selection->alias === null
161-
? $selection->name->value
162-
: $selection->alias->value;
164+
// Not respecting aliases because they are only relevant for clients
165+
// and the tracing we extract here is targeted at server developers.
166+
$selectionSet[] = $selection->name->value;
163167
}
164168

165169
sort($selectionSet, SORT_STRING);
@@ -169,6 +173,10 @@ private function extractOperationNames(OperationDefinitionNode $operation): arra
169173

170174
public static function supported(): bool
171175
{
172-
return class_exists(StartRequest::class);
176+
if (!class_exists(StartRequest::class) || !class_exists(StartExecution::class)) {
177+
return false;
178+
}
179+
180+
return property_exists(StartExecution::class, 'query');
173181
}
174182
}

src/Sentry/Laravel/Tracing/ServiceProvider.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\View\Factory as ViewFactory;
1212
use InvalidArgumentException;
1313
use Laravel\Lumen\Application as Lumen;
14+
use RuntimeException;
1415
use Sentry\Laravel\BaseServiceProvider;
1516
use Sentry\Serializer\RepresentationSerializer;
1617
use Throwable;
@@ -132,7 +133,18 @@ private function bootIntegrations(): void
132133
$this->getUserConfig()['tracing_integrations'] ?? []
133134
);
134135

136+
/** @var \Sentry\Laravel\Tracing\Integrations\IntegrationInterface $tracingIntegration */
135137
foreach ($integrations as $tracingIntegration) {
138+
if (!is_subclass_of($tracingIntegration, Integrations\IntegrationInterface::class)) {
139+
throw new RuntimeException(
140+
sprintf('Sentry tracing integrations should an instance of `%s`.', Integrations\IntegrationInterface::class)
141+
);
142+
}
143+
144+
if (!$tracingIntegration::supported()) {
145+
continue;
146+
}
147+
136148
try {
137149
$this->app->make($tracingIntegration);
138150
} catch (Throwable $e) {

0 commit comments

Comments
 (0)