Skip to content

Commit 0d83b51

Browse files
authored
Merge pull request #66 from codex-team/feature/add-should-handle-error-method-in-handler
Enhance error handling logic by adding `shouldHandleError` method and updating `Options` class
2 parents 1e12f85 + 60b1d64 commit 0d83b51

4 files changed

Lines changed: 144 additions & 52 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "PHP errors Catcher module for Hawk.so",
44
"keywords": ["hawk", "php", "error", "catcher"],
55
"type": "library",
6-
"version": "2.2.6",
6+
"version": "2.2.7",
77
"license": "MIT",
88
"require": {
99
"ext-curl": "*",

src/Handler.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ public function handleError(int $level, string $message, string $file, int $line
200200
$eventPayload = $this->eventPayloadBuilder->create($data);
201201
$event = $this->buildEvent($eventPayload);
202202

203-
if ($event !== null) {
203+
if ($event !== null && $this->shouldHandleError($level, $isSilencedError)) {
204204
$this->send($event);
205+
}
205206

206-
if (null !== $this->previousErrorHandler) {
207-
return false !== ($this->previousErrorHandler)($level, $message, $file, $line);
208-
}
207+
if (null !== $this->previousErrorHandler) {
208+
return false !== ($this->previousErrorHandler)($level, $message, $file, $line);
209209
}
210210

211211
return false;
@@ -335,6 +335,18 @@ public function buildEvent(EventPayload $eventPayload): ?Event
335335
);
336336
}
337337

338+
/**
339+
* Determines if the error should be handled, considering its level and if it was silenced using (@).
340+
*/
341+
private function shouldHandleError(int $level, bool $silenced): bool
342+
{
343+
if ($silenced) {
344+
return $this->options->shouldCaptureSilencedErrors();
345+
}
346+
347+
return ($this->options->getErrorTypes() & $level) !== 0;
348+
}
349+
338350
/**
339351
* Send the event to the remote server.
340352
*/

src/Options.php

Lines changed: 126 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,88 +5,168 @@
55
namespace Hawk;
66

77
/**
8-
* Class Options is responsible for configuring catcher
9-
*
10-
* @package Hawk
8+
* Class Options is responsible for configuring the Hawk catcher.
119
*/
1210
class Options
1311
{
1412
/**
15-
* Default available options
16-
*
17-
* @var array
13+
* @var string
14+
*/
15+
private $integrationToken = '';
16+
17+
/**
18+
* @var string
1819
*/
19-
private $options = [
20-
'integrationToken' => '',
21-
'url' => 'https://k1.hawk.so/',
22-
'release' => '',
23-
'error_types' => \E_ALL,
24-
'beforeSend' => null,
25-
'timeout' => 10,
20+
private $url = 'https://k1.hawk.so/';
21+
22+
/**
23+
* @var string
24+
*/
25+
private $release = '';
26+
27+
/**
28+
* @var int|null
29+
*/
30+
private $errorTypes = null;
31+
32+
/**
33+
* @var bool
34+
*/
35+
private $captureSilencedErrors = false;
36+
37+
/**
38+
* @var callable|null
39+
*/
40+
private $beforeSend = null;
41+
42+
/**
43+
* @var int
44+
*/
45+
private $timeout = 10;
46+
47+
/**
48+
* Map of accepted option keys to class properties.
49+
*/
50+
private const OPTION_KEYS = [
51+
'integrationToken' => 'integrationToken',
52+
'integration_token' => 'integrationToken',
53+
'url' => 'url',
54+
'release' => 'release',
55+
'errorTypes' => 'errorTypes',
56+
'error_types' => 'errorTypes',
57+
'captureSilencedErrors' => 'captureSilencedErrors',
58+
'capture_silenced_errors' => 'captureSilencedErrors',
59+
'beforeSend' => 'beforeSend',
60+
'before_send' => 'beforeSend',
61+
'timeout' => 'timeout',
2662
];
2763

2864
/**
2965
* Options constructor.
3066
*
31-
* @param array $options
67+
* @param array $options Associative array of options to initialize.
3268
*/
3369
public function __construct(array $options = [])
3470
{
35-
$this->options = array_merge($this->options, $options);
71+
foreach ($options as $key => $value) {
72+
$normalizedKey = self::OPTION_KEYS[$key] ?? null;
73+
74+
if ($normalizedKey === null) {
75+
throw new \InvalidArgumentException("Unknown option: $key");
76+
}
77+
78+
$this->setOption($normalizedKey, $value);
79+
}
3680
}
3781

3882
/**
39-
* Returns access token. It is available on projects settings
83+
* Set a class property based on the normalized option key.
4084
*
41-
* @return string
85+
* @param string $key
86+
* @param mixed $value
4287
*/
43-
public function getIntegrationToken(): string
88+
private function setOption(string $key, $value): void
4489
{
45-
return $this->options['integrationToken'];
90+
switch ($key) {
91+
case 'integrationToken':
92+
case 'release':
93+
case 'url':
94+
if (!is_string($value)) {
95+
throw new \InvalidArgumentException("Option '$key' must be a string.");
96+
}
97+
$this->$key = $value;
98+
99+
break;
100+
101+
case 'errorTypes':
102+
if (!is_int($value) && $value !== null) {
103+
throw new \InvalidArgumentException("Option 'errorTypes' must be an integer or null.");
104+
}
105+
$this->errorTypes = $value;
106+
107+
break;
108+
109+
case 'captureSilencedErrors':
110+
if (!is_bool($value)) {
111+
throw new \InvalidArgumentException("Option 'captureSilencedErrors' must be a boolean.");
112+
}
113+
$this->captureSilencedErrors = $value;
114+
115+
break;
116+
117+
case 'beforeSend':
118+
if (!is_callable($value) && $value !== null) {
119+
throw new \InvalidArgumentException("Option 'beforeSend' must be callable or null.");
120+
}
121+
$this->beforeSend = $value;
122+
123+
break;
124+
125+
case 'timeout':
126+
if (!is_int($value)) {
127+
throw new \InvalidArgumentException("Option 'timeout' must be an integer.");
128+
}
129+
$this->timeout = $value;
130+
131+
break;
132+
133+
default:
134+
throw new \InvalidArgumentException("Unknown option '$key'.");
135+
}
46136
}
47137

48-
/**
49-
* Returns URL that should be send
50-
*
51-
* @return string
52-
*/
53-
public function getUrl(): string
138+
public function getIntegrationToken(): string
54139
{
55-
return $this->options['url'];
140+
return $this->integrationToken;
56141
}
57142

58-
public function getTimeout(): int
143+
public function getUrl(): string
59144
{
60-
return $this->options['timeout'];
145+
return $this->url;
61146
}
62147

63-
/**
64-
* Returns application release
65-
*
66-
* @return string
67-
*/
68148
public function getRelease(): string
69149
{
70-
return $this->options['release'];
150+
return $this->release;
71151
}
72152

73-
/**
74-
* Returns error types
75-
*
76-
* @return int
77-
*/
78153
public function getErrorTypes(): int
79154
{
80-
return $this->options['error_types'];
155+
return $this->errorTypes ?? error_reporting();
156+
}
157+
158+
public function shouldCaptureSilencedErrors(): bool
159+
{
160+
return $this->captureSilencedErrors;
81161
}
82162

83-
/**
84-
* Returns before send callback
85-
*
86-
* @return callable|null
87-
*/
88163
public function getBeforeSend(): ?callable
89164
{
90-
return $this->options['beforeSend'];
165+
return $this->beforeSend;
166+
}
167+
168+
public function getTimeout(): int
169+
{
170+
return $this->timeout;
91171
}
92172
}

tests/Unit/OptionsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function testDefaultOptions(): void
1717
$this->assertEmpty($options->getIntegrationToken());
1818
$this->assertEmpty($options->getRelease());
1919
$this->assertEquals('https://k1.hawk.so/', $options->getUrl());
20-
$this->assertEquals(\E_ALL, $options->getErrorTypes());
20+
$this->assertEquals(error_reporting(), $options->getErrorTypes());
2121
}
2222

2323
public function testCustomOptions(): void

0 commit comments

Comments
 (0)