Skip to content

Commit d8e2adf

Browse files
Error Reporting: Client Side Support (#94)
* Error Reporting: Client Side Support * fix: formatting Co-authored-by: JRitchieAO <[email protected]> * documentation update --------- Co-authored-by: JRitchieAO <[email protected]>
1 parent 63cba75 commit d8e2adf

22 files changed

+2553
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
vendor
22
composer.lock
33
/.php-cs-fixer.cache
4+
5+
/node_modules

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Based on original work for App Engine ([GaeSupportL5](https://github.com/shpasse
3030
* **Google Cloud Operations Suite** integration
3131
* **Cloud Logging** destination with structured logs (see [docs/logging.md](docs/logging.md)).
3232
* **Error Reporting** integration for aggregation of reported exceptions (see [docs/logging.md](docs/logging.md#error-reporting)).
33+
* **Client Side JavaScript Error** ingestion (see [docs/client-side-error-report.md](docs/client-side-error-reporting.md)).
3334
* **Cloud Trace** (via [opentelemetry](https://github.com/open-telemetry/opentelemetry-php)) (see [docs/trace.md](docs/trace.md))
3435
* Distributed trace propagation via [Guzzle](src/AffordableMobiles/GServerlessSupportLaravel/Trace/Instrumentation/Guzzle/GuzzleInstrumentation.php#L70).
3536
* Integration with [laravel-debugbar](https://github.com/barryvdh/laravel-debugbar) (optional, see [docs/debugbar.md](docs/debugbar.md)).
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Client-Side JavaScript Error Reporting for Laravel
2+
3+
This package provides a robust, zero-dependency solution for capturing client-side JavaScript errors and unhandled promise rejections, and logging them to Google Cloud Error Reporting.
4+
5+
It automatically captures and transforms stack traces into a V8-compatible format, ensuring errors are grouped correctly within the Google Cloud console.
6+
7+
![Client Side Error Reporting Screenshot](images/client-side-error-reporting.png)
8+
9+
## Features
10+
11+
* **Seamless Integration with Google Cloud**: Client-side errors are reported directly to Google Cloud Error Reporting, appearing alongside your server-side exceptions.
12+
* **Correlated Logging**: Errors are logged against the `traceId` of the initial page load request. This allows you to easily find all client-side errors generated from a specific server request in the Log Viewer.
13+
* **User Tracking**: When configured, a user identifier is sent with each error report, allowing you to see how many users are affected by a specific issue directly within the Error Reporting UI.
14+
15+
## Installation & Setup
16+
17+
1. **Enable the Service Provider**
18+
19+
In your `bootstrap/app.php` file, add the service provider to the `withProviders` array:
20+
21+
```php
22+
->withProviders([
23+
// ... other providers
24+
\AffordableMobiles\GServerlessSupportLaravel\Integration\ErrorReporting\ClientSideJavaScript\ClientSideJavaScriptErrorReportingServiceProvider::class,
25+
])
26+
```
27+
28+
2. **Publish and Configure**
29+
30+
First, publish the package's dedicated configuration file:
31+
32+
```sh
33+
php artisan vendor:publish --tag="js-error-reporter-config"
34+
```
35+
36+
This will create a new configuration file at `config/js-error-reporter.php`.
37+
38+
Open this file to configure the reporter.
39+
40+
At a minimum, you must enable it:
41+
42+
```php
43+
// config/js-error-reporter.php
44+
45+
return [
46+
// Enable or disable the entire feature.
47+
'enabled' => true,
48+
49+
// ... other options
50+
];
51+
```
52+
53+
3. **Important: Cookie Encryption**
54+
55+
If you are using a `'cookie'` source for the `user_identifier` and that cookie is **not** set by Laravel (e.g., it's a platform-level or legacy cookie), you **must** prevent Laravel from trying to encrypt it.
56+
57+
In `bootstrap/app.php`, add the cookie name to the exceptions list for the `EncryptCookies` middleware:
58+
59+
```php
60+
->withMiddleware(function (Middleware $middleware) {
61+
$middleware->encryptCookies(except: [
62+
'__global_session_id', // <-- Add your cookie name here
63+
]);
64+
})
65+
```
66+
67+
4. **Include the Blade Partial**
68+
69+
Finally, include the provided Blade partial in your main application layout, inside the `<head>` tag.
70+
71+
This ensures the error handlers are registered as early as possible.
72+
73+
```php
74+
{{-- resources/views/layouts/app.blade.php --}}
75+
<head>
76+
...
77+
{{-- Include the Client-Side Error Reporter --}}
78+
@include('gss-js-error-reporting::partials.error-reporter-init')
79+
...
80+
</head>
81+
```
82+
83+
5. **Configure Authentication (Optional)**
84+
85+
By default, the package protects the reporting endpoint from cross-domain requests by ensuring the Host and Referer headers match.
86+
87+
You can customize this behavior by providing a custom authentication closure in the `config/js-error-reporter.php` file.
88+
89+
Setting the value to null will disable authentication.
90+
91+
```php
92+
// config/js-error-reporter.php
93+
94+
'authentication' => function (\Illuminate\Http\Request $request) {
95+
// Example: Allow requests only from specific subdomains
96+
$refererHost = parse_url($request->header('referer'), PHP_URL_HOST);
97+
return str_ends_with($refererHost, '.yourdomain.com');
98+
},
99+
```
100+
101+
## Improving Stack Trace Accuracy (Optional)
102+
103+
For the most accurate and readable stack traces in Google Cloud Error Reporting, it is highly recommended to generate JavaScript source maps (`.js.map` files) during your asset build process. The error reporting library will automatically use these maps to translate minified production code back into its original, readable source.
104+
105+
**Important Note:** Enabling source maps for production builds will make your original, un-minified JavaScript code (including comments) visible to anyone who uses the browser's developer tools. For most applications, the benefit to debugging outweighs this consideration.
106+
107+
**Enabling Source Maps in Vite**
108+
109+
In your project's `vite.config.js` file, set the `build.sourcemap` option to `true`:
110+
111+
```js
112+
// vite.config.js
113+
import { defineConfig } from 'vite';
114+
115+
export default defineConfig({
116+
// ...
117+
build: {
118+
sourcemap: true,
119+
},
120+
});
121+
```
122+
123+
**Enabling Source Maps in Laravel Mix**
124+
125+
In your project's `webpack.mix.js` file, chain the `.sourceMaps()` method in your production environment block:
126+
127+
```js
128+
// webpack.mix.js
129+
const mix = require('laravel-mix');
130+
131+
mix.js('resources/js/app.js', 'public/js');
132+
133+
if (mix.inProduction()) {
134+
mix.version().sourceMaps();
135+
}
136+
```
137+
138+
## Deployment
139+
140+
The package includes versioned JavaScript assets. To ensure the correct assets are always published during your deployment pipeline, make sure the `g-serverless:publish-assets` command is called.
141+
142+
**If you are using the `g-serverless:prepare` command, this is handled for you automatically.**
270 KB
Loading

0 commit comments

Comments
 (0)