diff --git a/.gitignore b/.gitignore
index 24df6ff..00f8568 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.idea
composer.lock
/vendor
+vendor
diff --git a/Helper/Data.php b/Helper/Data.php
index a3f48ac..28252bb 100644
--- a/Helper/Data.php
+++ b/Helper/Data.php
@@ -3,7 +3,6 @@
namespace JustBetter\Sentry\Helper;
use ErrorException;
-use InvalidArgumentException;
use JustBetter\Sentry\Block\SentryScript;
use Magento\Framework\App\Area;
use Magento\Framework\App\Config\ScopeConfigInterface;
@@ -25,6 +24,35 @@ class Data extends AbstractHelper
public const XML_PATH_SRS = 'sentry/general/';
public const XML_PATH_SRS_ISSUE_GROUPING = 'sentry/issue_grouping/';
+ public const NATIVE_SENTRY_CONFIG_KEYS = [
+ // https://docs.sentry.io/platforms/php/configuration/options/#core-options
+ 'dsn' => ['type' => 'string'],
+ 'environment' => ['type' => 'string'],
+ 'max_breadcrumbs' => ['type' => 'int'],
+ 'attach_stacktrace' => ['type' => 'bool'],
+ 'send_default_pii' => ['type' => 'bool'],
+ 'server_name' => ['type' => 'string'],
+ 'in_app_include' => ['type' => 'array'],
+ 'in_app_exclude' => ['type' => 'array'],
+ 'max_request_body_size' => ['type' => 'string'],
+ 'max_value_length' => ['type' => 'int'],
+ // https://docs.sentry.io/platforms/php/configuration/options/#error-monitoring-options
+ 'sample_rate' => ['type' => 'float'],
+ 'ignore_exceptions' => ['type' => 'array'],
+ 'error_types' => ['type' => 'int'],
+ 'context_lines' => ['type' => 'int'],
+ // https://docs.sentry.io/platforms/php/configuration/options/#tracing-options
+ 'traces_sample_rate' => ['type' => 'float'],
+ 'ignore_transactions' => ['type' => 'array'],
+ 'trace_propagation_targets' => ['type' => 'array'],
+ // https://docs.sentry.io/platforms/php/profiling/#enabling-profiling
+ 'profiles_sample_rate' => ['type' => 'float'],
+ // https://docs.sentry.io/platforms/php/configuration/options/#transport-options
+ 'http_proxy' => ['type' => 'string'],
+ 'http_connect_timeout' => ['type' => 'int'],
+ 'http_timeout' => ['type' => 'int'],
+ ];
+
/**
* @var ScopeConfigInterface
*/
@@ -39,22 +67,19 @@ class Data extends AbstractHelper
* @var array
*/
protected $configKeys = [
- 'dsn',
- 'logrocket_key',
- 'log_level',
- 'errorexception_reporting',
- 'ignore_exceptions',
- 'mage_mode_development',
- 'environment',
- 'js_sdk_version',
- 'tracing_enabled',
- 'tracing_sample_rate',
- 'performance_tracking_enabled',
- 'performance_tracking_excluded_areas',
- 'profiles_sample_rate',
- 'ignore_js_errors',
- 'disable_default_integrations',
- 'clean_stacktrace',
+ ...self::NATIVE_SENTRY_CONFIG_KEYS,
+ 'logrocket_key' => ['type' => 'array'],
+ 'log_level' => ['type' => 'int'],
+ 'errorexception_reporting' => ['type' => 'int'], /* @deprecated by @see: error_types https://docs.sentry.io/platforms/php/configuration/options/#error_types */
+ 'mage_mode_development' => ['type' => 'bool'],
+ 'js_sdk_version' => ['type' => 'string'],
+ 'tracing_enabled' => ['type' => 'bool'],
+ 'tracing_sample_rate' => ['type' => 'float'], /* @deprecated by @see: traces_sample_rate https://docs.sentry.io/platforms/php/configuration/options/#error_types */
+ 'performance_tracking_enabled' => ['type' => 'bool'],
+ 'performance_tracking_excluded_areas' => ['type' => 'array'],
+ 'ignore_js_errors' => ['type' => 'array'],
+ 'disable_default_integrations' => ['type' => 'array'],
+ 'clean_stacktrace' => ['type' => 'bool'],
];
/**
@@ -91,16 +116,6 @@ public function getDSN()
return $this->collectModuleConfig()['dsn'];
}
- /**
- * Get sample rate for php profiling.
- *
- * @return float
- */
- public function getPhpProfileSampleRate(): float
- {
- return (float) ($this->collectModuleConfig()['profiles_sample_rate'] ?? 0);
- }
-
/**
* Whether tracing is enabled.
*/
@@ -114,7 +129,7 @@ public function isTracingEnabled(): bool
*/
public function getTracingSampleRate(): float
{
- return (float) ($this->collectModuleConfig()['tracing_sample_rate'] ?? 0.2);
+ return (float) ($this->collectModuleConfig()['traces_sample_rate'] ?? $this->collectModuleConfig()['tracing_sample_rate'] ?? 0.2);
}
/**
@@ -132,25 +147,7 @@ public function getDisabledDefaultIntegrations(): array
*/
public function getIgnoreJsErrors()
{
- $list = $this->collectModuleConfig()['ignore_js_errors'];
-
- if ($list === null) {
- return null;
- }
-
- try {
- $config = $this->collectModuleConfig();
- $list = is_array($config['ignore_js_errors'])
- ? $config['ignore_js_errors']
- : $this->serializer->unserialize($config['ignore_js_errors']);
- } catch (InvalidArgumentException $e) {
- throw new RuntimeException(
- __('Sentry configuration error: `ignore_js_errors` has to be an array or `null`. Given type: %s', gettype($list)), // phpcs:ignore
- $e
- );
- }
-
- return $list;
+ return $this->collectModuleConfig()['ignore_js_errors'];
}
/**
@@ -229,13 +226,16 @@ public function collectModuleConfig(): array
$this->config[$storeId]['enabled'] = $this->scopeConfig->getValue('sentry/environment/enabled', ScopeInterface::SCOPE_STORE)
?? $this->deploymentConfig->get('sentry') !== null;
} catch (TableNotFoundException|FileSystemException|RuntimeException $e) {
- $this->config[$storeId]['enabled'] = null;
+ $this->config[$storeId]['enabled'] = $this->deploymentConfig->get('sentry') !== null;
}
- foreach ($this->configKeys as $value) {
+ foreach ($this->configKeys as $value => $config) {
try {
- $this->config[$storeId][$value] = $this->scopeConfig->getValue('sentry/environment/'.$value, ScopeInterface::SCOPE_STORE)
- ?? $this->deploymentConfig->get('sentry/'.$value);
+ $this->config[$storeId][$value] = $this->processConfigValue(
+ $this->scopeConfig->getValue('sentry/environment/'.$value, ScopeInterface::SCOPE_STORE)
+ ?? $this->deploymentConfig->get('sentry/'.$value),
+ $config
+ );
} catch (TableNotFoundException|FileSystemException|RuntimeException $e) {
$this->config[$storeId][$value] = null;
}
@@ -244,6 +244,30 @@ public function collectModuleConfig(): array
return $this->config[$storeId];
}
+ /**
+ * Parse the config value to the type defined in the config.
+ *
+ * @param mixed $value
+ * @param array $config
+ *
+ * @return mixed
+ */
+ public function processConfigValue(mixed $value, array $config): mixed
+ {
+ if ($value === null) {
+ return null;
+ }
+
+ return match ($config['type']) {
+ 'array' => is_array($value) ? $value : $this->serializer->unserialize($value),
+ 'int' => (int) $value,
+ 'float' => (float) $value,
+ 'bool' => (bool) $value,
+ 'string' => (string) $value,
+ default => $value,
+ };
+ }
+
/**
* Whether Sentry is active.
*
@@ -510,9 +534,9 @@ public function stripStoreCode(): bool
*
* @return int
*/
- public function getErrorExceptionReporting(): int
+ public function getErrorTypes(): int
{
- return (int) ($this->collectModuleConfig()['errorexception_reporting'] ?? error_reporting());
+ return (int) ($this->collectModuleConfig()['error_types'] ?? $this->collectModuleConfig()['errorexception_reporting'] ?? error_reporting());
}
/**
@@ -522,16 +546,7 @@ public function getErrorExceptionReporting(): int
*/
public function getIgnoreExceptions(): array
{
- $config = $this->collectModuleConfig();
- if (is_array($config['ignore_exceptions'])) {
- return $config['ignore_exceptions'];
- }
-
- try {
- return $this->serializer->unserialize($config['ignore_exceptions']);
- } catch (InvalidArgumentException $e) {
- return [];
- }
+ return $this->collectModuleConfig()['ignore_exceptions'] ?? [];
}
/**
@@ -543,7 +558,7 @@ public function getIgnoreExceptions(): array
*/
public function shouldCaptureException(Throwable $ex): bool
{
- if ($ex instanceof ErrorException && !($ex->getSeverity() & $this->getErrorExceptionReporting())) {
+ if ($ex instanceof ErrorException && !($ex->getSeverity() & $this->getErrorTypes())) {
return false;
}
diff --git a/Plugin/GlobalExceptionCatcher.php b/Plugin/GlobalExceptionCatcher.php
index eaaa87d..6bc787d 100755
--- a/Plugin/GlobalExceptionCatcher.php
+++ b/Plugin/GlobalExceptionCatcher.php
@@ -51,8 +51,32 @@ public function aroundLaunch(AppInterface $subject, callable $proceed)
return $proceed();
}
+ $config = $this->prepareConfig();
+
+ $this->sentryInteraction->initialize(array_filter($config->getData()));
+ $this->sentryPerformance->startTransaction($subject);
+
+ try {
+ return $response = $proceed();
+ } catch (Throwable $exception) {
+ $this->sentryInteraction->captureException($exception);
+
+ throw $exception;
+ } finally {
+ $this->sentryPerformance->finishTransaction($response ?? 500);
+ }
+ }
+
+ /**
+ * Prepare all the config passed to sentry.
+ *
+ * @return DataObject
+ */
+ public function prepareConfig(): DataObject
+ {
/** @var DataObject $config */
$config = $this->dataObjectFactory->create();
+ $config->setData(array_intersect_key($this->sentryHelper->collectModuleConfig(), SentryHelper::NATIVE_SENTRY_CONFIG_KEYS));
$config->setDsn($this->sentryHelper->getDSN());
if ($release = $this->releaseIdentifier->getReleaseId()) {
@@ -63,6 +87,36 @@ public function aroundLaunch(AppInterface $subject, callable $proceed)
$config->setEnvironment($environment);
}
+ $config->setBeforeBreadcrumb(function (\Sentry\Breadcrumb $breadcrumb): ?\Sentry\Breadcrumb {
+ $data = $this->dataObjectFactory->create();
+ $data->setBreadcrumb($breadcrumb);
+ $this->eventManager->dispatch('sentry_before_breadcrumb', [
+ 'sentry_breadcrumb' => $data,
+ ]);
+
+ return $data->getBreadcrumb();
+ });
+
+ $config->setBeforeSendTransaction(function (\Sentry\Event $transaction): ?\Sentry\Event {
+ $data = $this->dataObjectFactory->create();
+ $data->setTransaction($transaction);
+ $this->eventManager->dispatch('sentry_before_send_transaction', [
+ 'sentry_transaction' => $data,
+ ]);
+
+ return $data->getTransaction();
+ });
+
+ $config->setBeforeSendCheckIn(function (\Sentry\Event $checkIn): ?\Sentry\Event {
+ $data = $this->dataObjectFactory->create();
+ $data->setCheckIn($checkIn);
+ $this->eventManager->dispatch('sentry_before_send_check_in', [
+ 'sentry_check_in' => $data,
+ ]);
+
+ return $data->getCheckIn();
+ });
+
$config->setBeforeSend(function (\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event {
$data = $this->dataObjectFactory->create();
$data->setEvent($event);
@@ -80,32 +134,18 @@ public function aroundLaunch(AppInterface $subject, callable $proceed)
static fn (IntegrationInterface $integration) => !in_array(get_class($integration), $disabledDefaultIntegrations)
));
- $config->setIgnoreExceptions($this->sentryHelper->getIgnoreExceptions());
- $config->setErrorTypes($this->sentryHelper->getErrorExceptionReporting());
+ $config->setErrorTypes($this->sentryHelper->getErrorTypes());
if ($this->sentryHelper->isPerformanceTrackingEnabled()) {
$config->setTracesSampleRate($this->sentryHelper->getTracingSampleRate());
- }
-
- if ($rate = $this->sentryHelper->getPhpProfileSampleRate()) {
- $config->setData('profiles_sample_rate', $rate);
+ } else {
+ $config->unsetTracesSampleRate(null);
}
$this->eventManager->dispatch('sentry_before_init', [
'config' => $config,
]);
- $this->sentryInteraction->initialize($config->getData());
- $this->sentryPerformance->startTransaction($subject);
-
- try {
- return $response = $proceed();
- } catch (Throwable $exception) {
- $this->sentryInteraction->captureException($exception);
-
- throw $exception;
- } finally {
- $this->sentryPerformance->finishTransaction($response ?? 500);
- }
+ return $config;
}
}
diff --git a/README.md b/README.md
index 9c4bc69..f3f90f1 100644
--- a/README.md
+++ b/README.md
@@ -40,12 +40,12 @@ This module uses the [Magento Deployment Configuration](https://devdocs.magento.
'logrocket_key' => 'example/example',
'environment' => null,
'log_level' => \Monolog\Logger::WARNING,
- 'errorexception_reporting' => E_ALL,
+ 'error_types' => E_ALL,
'ignore_exceptions' => [],
'mage_mode_development' => false,
'js_sdk_version' => \JustBetter\Sentry\Block\SentryScript::CURRENT_VERSION,
'tracing_enabled' => true,
- 'tracing_sample_rate' => 0.5,
+ 'traces_sample_rate' => 0.5,
'disable_default_integrations' => [
\Sentry\Integration\ModulesIntegration::class,
]
@@ -64,13 +64,13 @@ Next to that there are some configuration options under Stores > Configuration >
| `dsn` | — | The DSN you got from Sentry for your project. You can find the DSN in the project settings under "Client Key (DSN)" |
| `environment` | — | Specify the environment under which the deployed version is running. Common values: production, staging, development. Helps differentiate errors between environments. |
| `log_level` | `\Monolog\Logger::WARNING` | Specify from which logging level on Sentry should get the messages. |
-| `errorexception_reporting` | `E_ALL` | If the Exception is an instance of [ErrorException](https://www.php.net/manual/en/class.errorexception.php), send the error to Sentry if it matches the error reporting. Uses the same syntax as [Error Reporting](https://www.php.net/manual/en/function.error-reporting.php), e.g., `E_ERROR` | E_WARNING`. |
+| `error_types` | `E_ALL` | If the Exception is an instance of [ErrorException](https://www.php.net/manual/en/class.errorexception.php), send the error to Sentry if it matches the error reporting. Uses the same syntax as [Error Reporting](https://www.php.net/manual/en/function.error-reporting.php), e.g., `E_ERROR` | E_WARNING`. |
| `ignore_exceptions` | `[]` | If the class being thrown matches any in this list, do not send it to Sentry, e.g., `[\Magento\Framework\Exception\NoSuchEntityException::class]` |
| `clean_stacktrace` | `true` | Whether unnecessary files (like Interceptor.php, Proxy.php, and Factory.php) should be removed from the stacktrace. (They will not be removed if they threw the error.) |
| `mage_mode_development` | `false` | If set to true, you will receive issues in Sentry even if Magento is running in develop mode. |
| `js_sdk_version` | `\JustBetter\Sentry\Block\SentryScript::CURRENT_VERSION` | If set, loads the explicit version of the JavaScript SDK of Sentry. |
| `tracing_enabled` | `false` | If set to true, tracing is enabled (bundle file is loaded automatically). |
-| `tracing_sample_rate` | `0.2` | If tracing is enabled, set the sample rate. |
+| `traces_sample_rate` | `0.2` | If tracing is enabled, set the sample rate. |
| `performance_tracking_enabled` | `false` | if performance tracking is enabled, a performance report got generated for the request. |
| `performance_tracking_excluded_areas` | `['adminhtml', 'crontab']` | if `performance_tracking_enabled` is enabled, we recommend to exclude the `adminhtml` & `crontab` area. |
| `profiles_sample_rate` | `0` (disabled) | if this option is larger than 0 (zero), the module will create a profile of the request. Please note that you have to install [Excimer](https://www.mediawiki.org/wiki/Excimer) on your server to use profiling. [Sentry documentation](https://docs.sentry.io/platforms/php/profiling/). You have to enable tracing too. |
@@ -88,9 +88,9 @@ using the "Variables" in Adobe Commerce using the following variables:
| `CONFIG__SENTRY__ENVIRONMENT__LOGROCKET_KEY` | string |
| `CONFIG__SENTRY__ENVIRONMENT__ENVIRONMENT` | string |
| `CONFIG__SENTRY__ENVIRONMENT__LOG_LEVEL` | integer |
-| `CONFIG__SENTRY__ENVIRONMENT__ERROREXCEPTION_REPORTING` | integer |
+| `CONFIG__SENTRY__ENVIRONMENT__ERROR_TYPES` | integer |
| `CONFIG__SENTRY__ENVIRONMENT__IGNORE_EXCEPTIONS` | JSON array of classes |
-| `CONFIG__SENTRY__ENVIRONMENT__CLEAN_STACKTRACE` | boolean |
+| `CONFIG__SENTRY__ENVIRONMENT__CLEAN_STACKTRACE` | boolean |
| `CONFIG__SENTRY__ENVIRONMENT__MAGE_MODE_DEVELOPMENT` | string |
| `CONFIG__SENTRY__ENVIRONMENT__JS_SDK_VERSION` | string |
| `CONFIG__SENTRY__ENVIRONMENT__TRACING_ENABLED` | boolean |
@@ -122,6 +122,12 @@ public function execute(\Magento\Framework\Event\Observer $observer)
Example: https://github.com/justbetter/magento2-sentry-filter-events
+This same thing is the case for
+| sentry_before_send | https://docs.sentry.io/platforms/php/configuration/options/#before_send |
+| sentry_before_send_transaction | https://docs.sentry.io/platforms/php/configuration/options/#before_send_transaction |
+| sentry_before_send_check_in | https://docs.sentry.io/platforms/php/configuration/options/#before_send_check_in |
+| sentry_before_breadcrumb | https://docs.sentry.io/platforms/php/configuration/options/#before_breadcrumb |
+
## Compatibility
The module is tested on Magento version 2.4.x with sentry sdk version 3.x. feel free to fork this project or make a pull request.
diff --git a/composer.json b/composer.json
index b299e15..71633f3 100755
--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,6 @@
"Performance"
],
"type": "magento2-module",
- "version": "4.1.0",
"license": "MIT",
"require": {
"php": ">=8.0",
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 4bc574d..e2ec49d 100755
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -125,7 +125,7 @@
1
-
+
validate-not-negative-number validate-number
diff --git a/etc/config.xml b/etc/config.xml
index 088648c..c620671 100755
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/view/adminhtml/templates/system/config/deployment-config-info.phtml b/view/adminhtml/templates/system/config/deployment-config-info.phtml
index ddf53e8..411be22 100644
--- a/view/adminhtml/templates/system/config/deployment-config-info.phtml
+++ b/view/adminhtml/templates/system/config/deployment-config-info.phtml
@@ -21,7 +21,7 @@
'logrocket_key' => 'example/example',
'environment' => null,
'log_level' => \Monolog\Logger::WARNING,
- 'errorexception_reporting' => E_ALL,
+ 'error_types' => E_ALL,
'ignore_exceptions' => [],
'mage_mode_development' => false,
]"); ?>