Bugsnag::sendException()   A
last analyzed

Complexity

Conditions 5
Paths 9

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 5
eloc 19
c 2
b 0
f 1
nc 9
nop 4
dl 0
loc 31
rs 9.3222
1
<?php
2
3
namespace Violet88\BugsnagModule;
4
5
use Bugsnag\Client;
6
use Bugsnag\Report;
7
use Composer\InstalledVersions;
8
use Exception;
9
use SilverStripe\Core\Environment;
10
use SilverStripe\Security\Security;
11
12
class Bugsnag
13
{
14
15
    public Client $bugsnag;
16
17
    protected $EXTRA_OPTIONS = array();
18
19
    public function __construct()
20
    {
21
        $this->bugsnag = Client::make(Environment::getEnv('BUGSNAG_API_KEY'));
22
        $this->bugsnag->setAppType('Silverstripe');
23
    }
24
25
    /**
26
     * Reset the custom metadata
27
     *
28
     * @return void
29
     */
30
    public function reset()
31
    {
32
        $this->EXTRA_OPTIONS = [];
33
    }
34
35
    /**
36
     * Get the standard severity set in the config.
37
     *
38
     * @return mixed
39
     */
40
    public function getStandardSeverity()
41
    {
42
        return Environment::getEnv('BUGSNAG_STANDARD_SEVERITY');
43
    }
44
45
    /**
46
     * Get the current custom metadata
47
     *
48
     * @return array
49
     */
50
    public function getExtraOptions()
51
    {
52
        return $this->EXTRA_OPTIONS;
53
    }
54
55
    /**
56
     * Add a key value pair to the metadata
57
     *
58
     * @param $key
59
     * @param $value
60
     * @return $this
61
     */
62
    public function addExtraOption($key, $value)
63
    {
64
        $this->EXTRA_OPTIONS[$key] = $value;
65
        return $this;
66
    }
67
68
    /**
69
     * Remove a key value pair from the metadata
70
     *
71
     * @param $key
72
     * @return $this
73
     */
74
    public function removeExtraOption($key)
75
    {
76
        unset($this->EXTRA_OPTIONS[$key]);
77
        return $this;
78
    }
79
80
    /**
81
     * Get the Bugsnag client
82
     *
83
     * @return Client
84
     */
85
    public function getBugsnag(): Client
86
    {
87
        return $this->bugsnag;
88
    }
89
90
    /**
91
     * This method send the exception to Bugsnag. Perform any configuration to your error report BEFORE you call this
92
     * method.
93
     *
94
     * @param Exception $exception
95
     * @param string|null $severity
96
     * @param bool $resetExtraOptions
97
     * @param bool $handled
98
     * @return void
99
     */
100
    public function sendException(
101
        Exception $exception,
102
        string $severity = null,
103
        bool $resetExtraOptions = true,
104
        bool $handled = true
105
    ) {
106
        $active = Environment::getEnv('BUGSNAG_ACTIVE');
107
        if ($active === 'true') {
108
            if (empty($severity)) {
109
                $severity = $this->getStandardSeverity();
110
            }
111
            if ($handled) {
112
                $this->getBugsnag()->notifyException(
113
                    $exception,
114
                    function (Report $report) use ($severity) {
115
                        $this->notifyCallback($report, $severity);
116
                    }
117
                );
118
            } else {
119
                $this->getBugsnag()->notify(
120
                    Report::fromPHPThrowable(
121
                        $this->getBugsnag()->getConfig(),
122
                        $exception
123
                    )->setUnhandled(true),
124
                    function (Report $report) use ($severity) {
125
                        $this->notifyCallback($report, $severity);
126
                    }
127
                );
128
            }
129
            if ($resetExtraOptions) {
130
                $this->reset();
131
            }
132
        }
133
    }
134
135
    /**
136
     * This method is for internal use only. It is called by sendException() to configure the error report
137
     *
138
     * @param Report $report
139
     * @param $severity
140
     * @return void
141
     */
142
    protected function notifyCallback(Report $report, $severity)
143
    {
144
        $report->setSeverity($severity);
145
        $report->setMetaData($this->getExtraOptions());
146
    }
147
148
    /**
149
     * Add the logged-in user to the error report. This user is automatically retrieved. When given no parameter,
150
     * it will add the user to the error report. When given false, it will remove the user from the error report.
151
     *
152
     * @param $bool
153
     * @return $this
154
     */
155
    public function addUserInfo($bool = true)
156
    {
157
        if ($bool) {
158
            if ($member = Security::getCurrentUser()) {
159
                $this->addExtraOption('User', array(
160
                    'Email' => $member->Email,
161
                    'FirstName' => $member->FirstName,
162
                    'Surname' => $member->Surname,
163
                    'ID' => $member->ID,
164
                    'Groups' => $member->Groups() ? $member->Groups()->column('Title') : [],
165
                ));
166
            }
167
        } else {
168
            $this->removeExtraOption('User');
169
        }
170
        return $this;
171
    }
172
173
    /**
174
     * Add the given version to the error report as the app version.
175
     *
176
     * @param $version
177
     * @return $this
178
     */
179
    public function setAppVersion($version)
180
    {
181
        $this->bugsnag->setAppVersion($version);
182
        return $this;
183
    }
184
185
    /**
186
     * Add the given type to the error report as the app type.
187
     *
188
     * @param $type
189
     * @return $this
190
     */
191
    public function setAppType($type)
192
    {
193
        $this->bugsnag->setAppType($type);
194
        return $this;
195
    }
196
197
    /**
198
     * Add the given stage to the error report as the release stage of the application.
199
     *
200
     * @param $version
201
     * @return $this
202
     */
203
    public function setReleaseStage($stage)
204
    {
205
        $this->bugsnag->setReleaseStage($stage);
206
        return $this;
207
    }
208
209
    /**
210
     * Send an error with the given message to Bugsnag
211
     *
212
     * @param $error
213
     * @return void
214
     */
215
    public function sendError($error)
216
    {
217
        $active = Environment::getEnv('BUGSNAG_ACTIVE');
218
        if ($active === 'true') {
219
            $this->bugsnag->notifyError('Error', $error);
220
        }
221
    }
222
223
    /**
224
     * Set the endpoint to which the error report is sent. This is useful for on premise bugsnag.
225
     *
226
     * @param $endpoint
227
     * @return $this
228
     */
229
    public function setEndpoint($endpoint)
230
    {
231
        $this->bugsnag->setNotifyEndpoint($endpoint);
232
        return $this;
233
    }
234
235
    /**
236
     * Add the version of the application, set in composer.json, to the error report. When given no parameter,
237
     * it will add the version to the error report. When given false, it will remove the version from the error report.
238
     *
239
     * @param bool $bool
240
     * @return $this
241
     */
242
    public function addVersion(bool $bool = true)
243
    {
244
        if ($bool) {
245
            $version = InstalledVersions::getRootPackage()['pretty_version'];
246
            $this->setAppVersion($version);
247
        } else {
248
            $this->removeExtraOption('Version');
249
        }
250
        return $this;
251
    }
252
253
    /**
254
     * Add the installed packages, without versions, to the error report. When given no parameter,
255
     * it will add the packages to the error report. When given false,
256
     * it will remove the packages from the error report.
257
     *
258
     * @param bool $bool
259
     * @return $this
260
     */
261
    public function addPackages(bool $bool = true)
262
    {
263
        if ($bool) {
264
            $packages = InstalledVersions::getInstalledPackages();
265
            $this->addExtraOption('Packages', $packages);
266
        } else {
267
            $this->removeExtraOption('Packages');
268
        }
269
        return $this;
270
    }
271
272
    /**
273
     * Add the installed packages, with their versions, to the error report. When given no parameter,
274
     * it will add the packages to the error report. When given false,
275
     * it will remove the packages from the error report.
276
     *
277
     * @param bool $bool
278
     * @return $this
279
     */
280
    public function addPackagesWithVersions(bool $bool = true)
281
    {
282
        if ($bool) {
283
            $packages = InstalledVersions::getInstalledPackages();
284
            $packagesWithVersions = [];
285
            foreach ($packages as $package) {
286
                $packagesWithVersions[$package] = InstalledVersions::getPrettyVersion($package);
287
            }
288
            $this->addExtraOption('Packages', $packagesWithVersions);
289
        } else {
290
            $this->removeExtraOption('Packages');
291
        }
292
        return $this;
293
    }
294
295
    /**
296
     * Send a new build release to Bugsnag. This is useful for matching versions with releases.
297
     *
298
     * @param $repository
299
     * @param $revision
300
     * @param $provider
301
     * @param $builderName
302
     * @return $this
303
     */
304
    public function notifyBuild($repository, $revision, $provider, $builderName)
305
    {
306
        $this->bugsnag->build($repository, $revision, $provider, $builderName);
307
        return $this;
308
    }
309
}
310