Skip to content

Commit

Permalink
Merge pull request #33 from flownative/task/refactor-to-throwablestorage
Browse files Browse the repository at this point in the history
Refactor to `ThrowableStorageInterface` implementation
  • Loading branch information
kdambekalns authored Nov 15, 2024
2 parents f1fa5a2 + 1f9bd5b commit 32ff214
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 143 deletions.
59 changes: 0 additions & 59 deletions Classes/Exception/DebugExceptionHandler.php

This file was deleted.

59 changes: 0 additions & 59 deletions Classes/Exception/ProductionExceptionHandler.php

This file was deleted.

12 changes: 12 additions & 0 deletions Classes/Log/CaptureResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);

namespace Flownative\Sentry\Log;

class CaptureResult {
public function __construct(
public readonly bool $suceess,
public readonly string $message,
public readonly string $eventId
) {}
}
94 changes: 94 additions & 0 deletions Classes/Log/SentryStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
declare(strict_types=1);

namespace Flownative\Sentry\Log;

use Flownative\Sentry\SentryClientTrait;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Log\ThrowableStorageInterface;

/**
* Captures a throwable to Sentry.
*
* @phpstan-consistent-constructor
* @Flow\Proxy(false)
* @Flow\Autowiring(false)
*/
class SentryStorage implements ThrowableStorageInterface
{
use SentryClientTrait;

/**
* Factory method to get an instance.
*
* @param array $options
* @return ThrowableStorageInterface
*/
public static function createWithOptions(array $options): ThrowableStorageInterface
{
return new static();
}

/**
* @param \Closure $requestInformationRenderer
* @return ThrowableStorageInterface
*/
public function setRequestInformationRenderer(\Closure $requestInformationRenderer): ThrowableStorageInterface
{
return $this;
}

/**
* @param \Closure $backtraceRenderer
* @return ThrowableStorageInterface
*/
public function setBacktraceRenderer(\Closure $backtraceRenderer): ThrowableStorageInterface
{
return $this;
}

/**
* Stores information about the given exception and returns information about
* the exception and where the details have been stored. The returned message
* can be logged or displayed as needed.
*
* The returned message follows this pattern:
* Exception #<code> in <line> of <file>: <message> - See also: <dumpFilename>
*
* @param \Throwable $throwable
* @param array $additionalData
* @return string Informational message about the stored throwable
*/
public function logThrowable(\Throwable $throwable, array $additionalData = []): string
{
$message = $this->getErrorLogMessage($throwable);
try {
if ($sentryClient = self::getSentryClient()) {
$captureResult = $sentryClient->captureThrowable($throwable, $additionalData);
if ($captureResult->suceess) {
$message .= ' (Sentry: #' . $captureResult->eventId . ')';
} else {
$message .= ' (Sentry: ' . $captureResult->message . ')';
}
}
} catch (\Throwable $e) {
$message .= ' – Error capturing message: ' . $this->getErrorLogMessage($e);
}

return $message;
}

protected function getErrorLogMessage(\Throwable $error): string
{
// getCode() does not always return an integer, e.g. in PDOException it can be a string
if (is_int($error->getCode()) && $error->getCode() > 0) {
$errorCodeString = ' #' . $error->getCode();
} else {
$errorCodeString = ' [' . $error->getCode() . ']';
}
$backTrace = $error->getTrace();
$line = isset($backTrace[0]['line']) ? ' in line ' . $backTrace[0]['line'] . ' of ' . $backTrace[0]['file'] : '';

return 'Exception' . $errorCodeString . $line . ': ' . $error->getMessage();
}
}
31 changes: 16 additions & 15 deletions Classes/SentryClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Flownative\Sentry\Context\UserContext;
use Flownative\Sentry\Context\UserContextServiceInterface;
use Flownative\Sentry\Context\WithExtraDataInterface;
use Flownative\Sentry\Log\CaptureResult;
use GuzzleHttp\Psr7\ServerRequest;
use Jenssegers\Agent\Agent;
use Neos\Flow\Annotations as Flow;
Expand Down Expand Up @@ -182,12 +183,19 @@ public function getOptions(): Options
return new Options();
}

public function captureThrowable(Throwable $throwable, array $extraData = [], array $tags = []): void
public function captureThrowable(Throwable $throwable, array $extraData = [], array $tags = []): CaptureResult
{
if (empty($this->dsn)) {
return;
return new CaptureResult(
false,
'Failed capturing message, because no Sentry DSN was set. Please check your settings.',
''
);
}

$message = '';
$sentryEventId = '';

if ($throwable instanceof WithReferenceCodeInterface) {
$extraData['Reference Code'] = $throwable->getReferenceCode();
}
Expand Down Expand Up @@ -215,20 +223,13 @@ public function captureThrowable(Throwable $throwable, array $extraData = [], ar
$this->addThrowableToEvent($throwable, $event);
$sentryEventId = SentrySdk::getCurrentHub()->captureEvent($event);
} else {
$sentryEventId = 'ignored';
}
if ($this->logger) {
$this->logger->log(
($captureException ? LogLevel::CRITICAL : LogLevel::NOTICE),
sprintf(
'Exception #%s: %s (Ref: %s | Sentry: %s)',
$throwable->getCode(),
$throwable->getMessage(),
($throwable instanceof WithReferenceCodeInterface ? $throwable->getReferenceCode() : '-'),
$sentryEventId
)
);
$message = 'ignored';
}
return new CaptureResult(
true,
$message,
(string)$sentryEventId
);
}

public function captureMessage(string $message, Severity $severity, array $extraData = [], array $tags = []): ?EventId
Expand Down
5 changes: 0 additions & 5 deletions Configuration/Development/Settings.yaml

This file was deleted.

5 changes: 0 additions & 5 deletions Configuration/Production/Settings.yaml

This file was deleted.

4 changes: 4 additions & 0 deletions Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ Neos:
log:
systemLogger:
backend: Flownative\Sentry\Log\SentryFileBackend
throwables:
storageClass: 'Flownative\Sentry\Log\SentryStorage'
optionsByImplementation:
'Flownative\Sentry\Log\SentryStorage': []

0 comments on commit 32ff214

Please sign in to comment.