Frontend Development 25 min read

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.

WecTeam
WecTeam
WecTeam
Mastering Front‑End Error Logging: From BadJS Collection to Deep Analysis

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

ErrorEvent

on

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

Error

object (its

stack

is 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

message

and

error.stack

to 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

null

stack. The standard mitigation is:

Add

Access-Control-Allow-Origin

on the script response.

Set the

crossorigin

attribute on the

&lt;script&gt;

tag (either

anonymous

or

use-credentials

).

When

use-credentials

is used, the server must also return

Access-Control-Allow-Credentials: true

and 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...catch

and 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

errorEvent

or

window.onerror

; optionally use

try...catch

for 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

crossorigin

to unblock details.

In hybrid iOS WebViews, prefer same‑origin scripts or explicit

try...catch

handling.

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.

Performance Monitoringlog analysiskibanabadjscros​s‑origin scriptfrontend error loggingjavascript exceptionswebview hybrid
WecTeam
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.