summaryrefslogtreecommitdiff
path: root/doc/development/fe_guide/logging.md
blob: 30cf290fbe82e51bec675f38e3ff9141352ed667 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

# Client-side logging for frontend development

This guide contains the best practices for client-side logging for GitLab
frontend development.

## When to log to the browser console

We do not want to log unnecessarily to the browser console, as excessively
noisy console logs are not easy to read, parse, or process. We **do** want to
give visibility to unintended events in the system. If a possible but unexpected
exception occurs during runtime, we want to log the details of this exception.
These logs can give significantly helpful context to end users creating issues, or
contributors diagnosing problems.

Whenever a `catch(e)` exists, and `e` is something unexpected, log the details.

### What makes an error unexpected?

Sometimes a caught exception can be part of normal operations. For instance, third-party
libraries might throw an exception based on certain inputs. If we can gracefully
handle these exceptions, then they are expected. Don't log them noisily.
For example:

```javascript
try {
  // Here, we call a method based on some user input.
  // `doAThing` will throw an exception if the input is invalid.
  const userInput = getUserInput();
  doAThing(userInput);
} catch (e) {
  if (e instanceof FooSyntaxError) {
    // To handle a `FooSyntaxError`, we just need to instruct the user to change their input.
    // This isn't unexpected, and is part of normal operations.
    setUserMessage(`Try writing better code. ${e.message}`);
  } else {
    // We're not sure what `e` is, so something unexpected and bad happened...
    logError(e);
    setUserMessage('Something unexpected happened...');
  }
}
```

## How to log an error

We have a helpful `~/lib/logger` module which encapsulates how we can
consistently log runtime errors in GitLab. Import `logError` from this
module, and use it as you normally would `console.error`. Pass the actual `Error`
object, so the stack trace and other details can be captured in the log:

```javascript
// 1. Import the logger module.
import { logError } from '~/lib/logger';

export const doThing = () => {
  return foo()
    .then(() => {
      // ...
    })
    .catch(e => {
      // 2. Use `logError` like you would `console.error`.
      logError('An unexpected error occurred while doing the thing', e);

      // We may or may not want to present that something bad happened to the end user.
      showThingFailed();
    });
};
```

## Relation to frontend observability

Client-side logging is strongly related to
[Frontend observability](https://about.gitlab.com/company/team/structure/working-groups/frontend-observability/).
We want unexpected errors to be observed by our monitoring systems, so
we can quickly react to user-facing issues. For a number of reasons, it is
unfeasible to send every log to the monitoring system. Don't shy away from using
`~/lib/logger`, but consider controlling which messages passed to `~/lib/logger`
are actually sent to the monitoring systems.

A cohesive logging module helps us control these side effects consistently
across the various entry points.