Drupal is a registered trademark of Dries Buytaert
CKEditor 5 Plugin Pack 1.5.4 Minor update available for module ckeditor5_plugin_pack (1.5.4). CKEditor 5 Premium Features 1.8.3 Minor update available for module ckeditor5_premium_features (1.8.3). CKEditor 4 LTS - WYSIWYG HTML editor 1.0.5 Minor update available for module ckeditor_lts (1.0.5). Dxpr Theme 8.1.4 Minor update available for theme dxpr_theme (8.1.4). Protected Content 10.1.123 Minor update available for module proc (10.1.123). OpenFed 13.6.6 Minor update available for distribution openfed (13.6.6). Commerce ML Starter 8.x-1.92 Minor update available for module cmlstarter (8.x-1.92). Entity Registry 1.0.4 Minor update available for module entity_registry (1.0.4). CKEditor 4 LTS - WYSIWYG HTML editor 7.x-1.28 Module ckeditor_lts updated after 17 months of inactivity (7.x-1.28). Provus Mega Menu Module provus_mega_menu crossed 1,000 active installs.

JSerror

Security covered
View on drupal.org

JSerror records the JavaScript errors your visitors actually hit and stores
them in your own database.

Code that works in your browser does not always work in everyone's. Errors
that only show up on one browser, one device or one locale are hard to find,
because nobody reports them and you cannot reproduce them locally. JSerror
catches them as they happen and puts them somewhere you can look.

Everything stays on your own server. No third party service sees your users
or the pages they were on.

How it works

JSerror puts a small script at the very top of the page, ahead of every
other script. That script installs an error handler and buffers whatever it
catches.

Being that early is the whole point. Errors thrown while your own JavaScript
is still downloading and parsing are the ones that break a page hardest, and a
monitoring script that loads normally does not exist yet when they happen.
JSerror is already listening.

The reporting script itself loads afterwards, once the page has finished
loading, and posts what was collected back to the site in batches. Capturing
errors never delays rendering, and if the reporter fails to load your page is
unaffected.

What gets recorded

For each error: the message, the script and the line and column it came
from, the page the visitor was on, the browser and operating system, the stack
trace when the browser gives one, and whether it happened before or after the
page finished loading.

That last one is more useful than it sounds. It tells you whether the page
never finished loading at all, or whether something broke later while someone
was using it.

Unhandled promise rejections are recorded too. Those never reach
window.onerror, so they are easy to miss.

Reading the report

Reports, then Recent JavaScript errors. Distinct errors are listed with the
most frequent first, grouped by message, so one broken line of code hit by ten
thousand visitors is a single row with a count rather than ten thousand
rows.

Open an entry to see the individual occurrences, with the pages, browsers
and platforms affected and any stack traces.

Filtering by browser or platform happens in the URL, so a filtered report is
a link you can paste into an issue.

Running it on a production site

The settings exist so this can be left switched on:

  • Log a percentage of visitors rather than all of them. The decision is made
    once per visitor and remembered, so a reduced sample still shows you whole
    sessions instead of scattered pages.
  • Cap how many reports a single page view can send, so a page stuck in an
    error loop cannot flood anything.
  • Cap how many reports the site will accept from one client per hour.
  • Trim the log to a fixed number of rows on cron.
  • Optionally keep captured errors out of the visitor's browser console.

The endpoint that receives reports accepts anonymous requests, because the
errors worth knowing about are the ones happening to ordinary visitors. It only
accepts same-origin JSON, so another site cannot get its visitors to write into
your log, it applies a size limit to every field before storing anything, and
it counts its rate limit in stored reports rather than in requests.

Requirements

Drupal 11. Nothing else.

Older versions of this module needed the Browscap module to work out the
browser and operating system. That is no longer the case and Browscap is not
required.

Installation

composer require drupal/jserror

Enable the module, then visit Configuration, Development, JSerror.

Permissions

  • View site reports to read the error report.
  • Administer JSerror to change the settings or clear the log.

Known limitation

JSerror depends on an inline script running before everything else on the
page, and that script carries no CSP nonce. On a site with a strict Content
Security Policy that does not permit inline scripts, it will not run and the
module will quietly do nothing. If you enforce a strict CSP you will need to
allow the script by hash.

Versions

1.0.x supports Drupal 11 and is a complete rewrite. There is no upgrade path
from the Drupal 7 branch, so install it as a new module and treat any old error
rows as throwaway.

7.x-1.x is unsupported.

Support

Bug reports, support requests and feature requests all belong in the issue
queue. Maintained by Abhishek Anand.

Activity

Total releases
2
First release
Jul 2026
Latest release
51 minutes ago
Releases (12 mo)
2 ▲ from 0
Maintenance
Active

Releases

Version Type Release date
1.0.0-alpha1 Pre-release Jul 29, 2026
1.0.x-dev Dev Jul 29, 2026