Mastering Front‑End Error Logging: From BadJS Collection to Deep Analysis
This article explains why front‑end error logging is essential, how BadJS (JavaScript runtime errors) are captured, enriched, and reported, and provides practical strategies for analyzing logs, handling Script errors, dealing with hybrid WebView environments, and scaling the system with big‑data pipelines.
Introduction
BadJS is a collective term for front‑end runtime exceptions such as "cannot find object", "undefined", or syntax errors. The author, responsible for a high‑traffic JD.com front‑end service, shares a systematic approach to collecting, reporting, and analyzing BadJS to quickly locate problems.
Why Build a BadJS System
In high‑traffic pages (millions of PV per day), a single front‑end error can cause user loss and revenue impact. Early detection prevents the "black‑hole" effect and protects developers' and product owners' interests.
BadJS Principles and Collection
When JavaScript throws an uncaught exception, the browser triggers an
ErrorEventon
window(or calls
window.onerror). Two global handlers are recommended:
<code>window.addEventListener('error', function (errorEvent) {
const { message, filename, lineno, colno, error } = errorEvent;
// process and send the data
});
window.onerror = function (message, source, lineno, colno, error) {
// fallback handling
};
</code>Both provide five key fields:
message,
filename/source,
lineno,
colno, and the
Errorobject (its
stackis crucial).
BadJS Reporting
Only necessary information should be sent to avoid overwhelming the server. Typical payload includes the error stack, a short business context, and automatically collected fields such as IP, timestamp, Referrer, User‑Agent, and cookies.
<code>var _img = new Image();
_img.src = url; // GET request (max 2048 chars)
</code>For larger payloads, switch to POST.
Example of a ready‑made reporter (bj‑report.js):
<code>BJ_REPORT.init({
id: 1,
uin: 123,
delay: 1000,
url: "//badjs2.qq.com/badjs",
ignore: [/Script error/i],
random: 1,
repeat: 5,
onReport: function (id, errObj) {},
submit: null,
ext: {},
offlineLog: false,
offlineLogExp: 5
});
</code>Data Analysis
Collected logs are stored in a big‑data pipeline (Logstash → Elasticsearch → Kibana). Kibana provides fast, indexed queries, while a simple reporting UI can be built for quick overviews. Analysts examine the
messageand
error.stackto pinpoint the offending file, line, and function.
Script Error Challenges
Cross‑origin scripts without proper CORS headers cause the browser to mask the real error as "Script error" with a
nullstack. The standard mitigation is:
Add
Access-Control-Allow-Originon the script response.
Set the
crossoriginattribute on the
<script>tag (either
anonymousor
use-credentials).
When
use-credentialsis used, the server must also return
Access-Control-Allow-Credentials: trueand a specific origin (not
*).
Hybrid WebView Considerations
In native apps that embed WebView, error behavior differs:
iOS WebView always reports cross‑origin async errors as "Script error".
Android WebView behaves like a regular browser and can capture full stack traces if CORS is configured.
Work‑arounds for iOS include converting cross‑origin scripts to same‑origin, wrapping them in
try...catchand manually dispatching an
ErrorEvent, or relying on Android data as a proxy.
Backend and Big Data Aspects
Daily BadJS volume is modest (≈0.67% of 24 billion total logs). Data retention is 5 days, with automatic sampling when traffic spikes. The first log system used raw HDFS + Impala (slow); the second migrated to Elasticsearch + Kibana, dramatically improving query speed and usability.
Best Practices Summary
Collect errors via
errorEventor
window.onerror; optionally use
try...catchfor special cases.
Report only essential fields; send via GET (image beacon) or POST for large payloads.
Analyze stack traces to locate code; use UA to infer environment and possible bot traffic.
For Script errors, enable CORS and
crossoriginto unblock details.
In hybrid iOS WebViews, prefer same‑origin scripts or explicit
try...catchhandling.
Conclusion
A robust BadJS system gives front‑end teams confidence, early error detection, and actionable insights, while also highlighting the need for backend support and resource planning.
WecTeam
WecTeam (维C团) is the front‑end technology team of JD.com’s Jingxi business unit, focusing on front‑end engineering, web performance optimization, mini‑program and app development, serverless, multi‑platform reuse, and visual building.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.