If you’ve had more than a year of hands-on front-end development experience, you’ll be familiar with screenshots like this one

These viral images have front-end developers scratching their heads.

In fact, most of the errors have nothing to do with the underlying framework, but because the underlying framework is at the bottom of the JS stack execution, the error stack of the business code is buried in a vast stack of functions.

Not to mention the confusing code after launch, without sourceMap, even the Buddha is not working.

And even if the error log reported by the client is restored through sourceMap, it is still swamped by a huge function stack because of various problems, either the number of lines of code does not match or the number of matches is only returned to the above situation.

If your error is the result of asynchronous execution, you have to go to the guan Gong, because there is no way to locate it.

Is there any way to make the client error log legible?

First let’s define the requirements for the logging tool

  1. No intrusion to business code, can run independently
  2. Logs should be clear and readable, with targeted filtering and post hoc analysis.

To build such a logging tool, one of the underlying technologies that meet the above requirements is responsive programming.

I’ve written several articles covering various aspects of front-end responsive programming, starting with a simple example of why such a logging tool can be implemented based on responsive programming.

The core of responsiveness is “events”

Reactive programming is a programming technique developed from event-based programming model. And the biggest difference is that we are used to imperative programming, reactive programming requires us to abstract things into smaller particle size, each other between each other through the incident response to complete a process, is the decentralized mode of thinking, and the imperative programming requires us to abstract a model able to command the center of the control process, on this basis to build a set of programming abstraction, It’s a centralized mindset.

What are the benefits of decentralization? Got rich 😁, kidding, because the decentralized nature of cryptocurrencies makes it hard to track and regulate cryptocurrency holders. The foundation of getting rich is breaking existing rules to make a lot of money, but I’m not here to discuss that.

But extending this idea, we can see that a decentralized approach to programming can avoid some of the problems that come with centralization.

  1. Overly complex and bloated command centers over time.
  2. The code is too stacked to break up

It is clear that decentralized programming can greatly reduce the maintenance cost of complex software, for example, patterns such as microservices can decompose a complex software application into several software applications with a single responsibility.

Up to now, front-end development has been a centralized programming mode in the development, but in fact, complex application maintenance has encountered great bottlenecks, and these can not be solved by intelligent and codeless, both of which are not very valuable to reduce the cost of maintenance stage. It can only shorten the development cycle and reduce the start-up cost of software.

But those of you who have studied software engineering should know that it is the software that goes live, especially the B-side software, that usually costs the most in software maintenance.

But back to the logging tool, let’s look at a simple example of how reactive programming logs code as it runs.

Let’s start by building a simple input box component. For ease of writing, I’ll use React

import React from 'react';
import { createComponent } from 'rdeco';

createComponent({
  name: 'input'.state: {
    value: ' ',},controller: {
    onChange(e) {
      this.setter.value(e.target.avlue); }},view: {
    render() {
      return <input type="text" onChange={this.controller.onChange} value={this.state.value} />; ,}}});Copy the code

This Input box does nothing special, just provides an Input component that we can Input, and we render it.

Now for the big part, as part of log minimization, let’s write a listener component to listen for input

const InputLogger = createComponent({
  name: 'input-logger'.state: {
    loggerList: ['no log'],},ref: {
    loggerList: []},subscribe: {
    input: {
      state: {
        value({ nextState }) {
          this.ref.loggerList.push(nextState); }},}},controller: {
    onClick() {
      console.log(this.ref.loggerList);
      this.setter.loggerList(this.ref.loggerList); }},view: {
    render() {
      return (
        <div>
          {this.state.loggerList.map((log) => {
            return <p key={log}>Input → State → value :: {log}</p>;
          })}
          <br />
          <button onClick={this.controller.onClick}> Print </button>
        </div>); ,}}});Copy the code

Then render the listener below the Input box, and let’s see what it looks like

OK, let’s recall that if the small example above were enlarged, if the logging tool could automatically capture the name of the component, the method Key called, and the parameters passed, enough to cover all the code. So we don’t have to worry about that.

To this end, we have added a pluginSubject to Rdeco, which implements the logging tool as a plug-in pattern. Based on pluginSubject, you can easily capture all the schemes called and parameters passed during the execution of the responsive object. And this information is stored according to the order in which the calls were executed.

I wrote an example of a simple logging plug-in that looks something like this

In this example, when the user clicked to login, the code hung because of a bug and threw an Error, so I’ve manually simulated a loginError event through this line of code

this.emit('loginError')
Copy the code

As you can see in the log, the last line is button.event.loginError.

Codesandbox.io /s/sleepy… You can do it yourself if you are interested.

I recently published a new column on responsive front-end programming, and we will continue to publish articles and practical techniques on this topic. If you are interested, you can follow my column juejin.cn/column/7038… And welcome to our git project github.com/kinop112365…