@vltpkg/error-cause 0.0.0-3 → 0.0.0-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +86 -93
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,25 +2,22 @@
2
2
 
3
3
  # @vltpkg/error-cause
4
4
 
5
- Utility functions for `Error` creation to help enforce vlt's `Error.cause` conventions.
5
+ Utility functions for `Error` creation to help enforce vlt's
6
+ `Error.cause` conventions.
6
7
 
7
- **[Usage](#usage)**
8
- ·
9
- **[Error Reporting](#challenges-of-error-reporting)**
10
- ·
11
- **[Conventions](#conventions)**
12
- ·
13
- **[Error Types](#error-types)**
8
+ **[Usage](#usage)** ·
9
+ **[Error Reporting](#challenges-of-error-reporting)** ·
10
+ **[Conventions](#conventions)** · **[Error Types](#error-types)**
14
11
 
15
12
  ## Why
16
13
 
17
- Most node programs have a mishmash of error codes and various
18
- `Error` subtypes, all in different shapes, making error handling
19
- and reporting more difficult at the top level. This negatively
20
- impacts debugging and user experience.
14
+ Most node programs have a mishmash of error codes and various `Error`
15
+ subtypes, all in different shapes, making error handling and reporting
16
+ more difficult at the top level. This negatively impacts debugging and
17
+ user experience.
21
18
 
22
- The JavaScript `Error` constructor has a [`cause`
23
- option](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause)
19
+ The JavaScript `Error` constructor has a
20
+ [`cause` option](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause)
24
21
  which is supported since Node 16.9. We should use it!
25
22
 
26
23
  This module makes that easy.
@@ -68,62 +65,60 @@ const checkBar = () => {
68
65
  }
69
66
  ```
70
67
 
71
- The functions will create an error object with a `cause` property
72
- if set, and the type checks will ensure that the `cause` object
73
- matches vlt's conventions.
68
+ The functions will create an error object with a `cause` property if
69
+ set, and the type checks will ensure that the `cause` object matches
70
+ vlt's conventions.
74
71
 
75
72
  ## Challenges of Error Reporting
76
73
 
77
74
  - Provide enough information to be useful. On full inspection, we
78
- should ideally always get back to not just the initial error
79
- that was thrown, but also all locations where the error might
80
- have been caught and handled in some way.
75
+ should ideally always get back to not just the initial error that
76
+ was thrown, but also all locations where the error might have been
77
+ caught and handled in some way.
81
78
  - Do not provide more information than is useful. Eg,
82
- `console.error(er)` should not fill the entire scrollback
83
- buffer.
84
- - New modules and libraries should have minimal friction in
85
- creating a new style of error when needed. This means, minimize
86
- the amount that any module needs to know about the errors
87
- raised by any other module, including especially top-level
88
- error handling.
89
- - _Some_ information about the error must be known to our
90
- top-level error handler, so that it can usefully report errors
91
- and suggest corrections.
79
+ `console.error(er)` should not fill the entire scrollback buffer.
80
+ - New modules and libraries should have minimal friction in creating a
81
+ new style of error when needed. This means, minimize the amount that
82
+ any module needs to know about the errors raised by any other
83
+ module, including especially top-level error handling.
84
+ - _Some_ information about the error must be known to our top-level
85
+ error handler, so that it can usefully report errors and suggest
86
+ corrections.
92
87
 
93
88
  ## Solution
94
89
 
95
90
  - A strictly upheld convention of Error object creation using the
96
91
  `cause` property.
97
- - Top level error handler can have special logic where necessary
98
- for known error codes, but will still be able to do something
99
- more useful when an Error object follows our conventions, even
100
- if it's not a code that it knows.
92
+ - Top level error handler can have special logic where necessary for
93
+ known error codes, but will still be able to do something more
94
+ useful when an Error object follows our conventions, even if it's
95
+ not a code that it knows.
101
96
 
102
97
  ## Conventions
103
98
 
104
- The following conventions should be followed for all `Error`
105
- creation and handling throughout the vlt codebase.
99
+ The following conventions should be followed for all `Error` creation
100
+ and handling throughout the vlt codebase.
106
101
 
107
102
  - **If you can't help, get out of the way.** Just let throws pass
108
103
  through to the top when nothing can be done to assist.
109
104
  - **Add information by using thrown error as `cause`.** Use a
110
105
  previously-thrown error as the `cause` option.
111
- - **Add even more info with a double-`cause`.** If more info can
112
- be added to a prior throw, nest the `cause` properties like
106
+ - **Add even more info with a double-`cause`.** If more info can be
107
+ added to a prior throw, nest the `cause` properties like
113
108
  `{ some, other, info, cause: priorError }`.
114
109
  - **Always set `cause`, even if no prior error.** Use a plain-old
115
110
  JavaScript object following our field conventions.
116
111
  - **Rare exception: synthetic ErrnoException style errors.** If we are
117
112
  doing something that is similar to a system operation, it's
118
113
  sometimes ok to mimic node's pattern.
119
- - **Do not subclass `Error`.** Just create a plain old Error, and
120
- set the `cause` with additional information.
114
+ - **Do not subclass `Error`.** Just create a plain old Error, and set
115
+ the `cause` with additional information.
121
116
 
122
117
  ### If you can't help, don't get in the way.
123
118
 
124
- Whenever possible, if no remediation or extra information can
125
- usefully be added, it's best to just not handle errors and let
126
- them be raised at the higher level. For example, instead of this:
119
+ Whenever possible, if no remediation or extra information can usefully
120
+ be added, it's best to just not handle errors and let them be raised
121
+ at the higher level. For example, instead of this:
127
122
 
128
123
  ```
129
124
  let data
@@ -142,9 +137,9 @@ const data = await readFile(someFile)
142
137
 
143
138
  ### Add information by using thrown error as `cause`.
144
139
 
145
- If we can add information or do something else useful for the
146
- user in understanding the problem, do so by creating a new
147
- `Error` and setting the original thrown error as the `cause`.
140
+ If we can add information or do something else useful for the user in
141
+ understanding the problem, do so by creating a new `Error` and setting
142
+ the original thrown error as the `cause`.
148
143
 
149
144
  ```js
150
145
  let data
@@ -158,9 +153,9 @@ try {
158
153
 
159
154
  ### Add even more info with a double-`cause`.
160
155
 
161
- If we can add even more information, that should ideally _not_ be
162
- put on the Error we throw, but on a `cause` object. Because
163
- `cause` objects can nest, we can do something like this:
156
+ If we can add even more information, that should ideally _not_ be put
157
+ on the Error we throw, but on a `cause` object. Because `cause`
158
+ objects can nest, we can do something like this:
164
159
 
165
160
  ```js
166
161
  let data
@@ -204,27 +199,25 @@ throw error('could not resolve', {
204
199
  })
205
200
  ```
206
201
 
207
- This makes any big objects easily skipped if we want to just
208
- output the error with `console.error()` or something, but still
209
- preserves any debugging information that might be useful all the
210
- way down the chain.
202
+ This makes any big objects easily skipped if we want to just output
203
+ the error with `console.error()` or something, but still preserves any
204
+ debugging information that might be useful all the way down the chain.
211
205
 
212
206
  ### Rare exception: synthetic ErrnoException style errors.
213
207
 
214
- In some rare low-level cases, there are operations we perform
215
- that are very similar to a node filesystem operation.
208
+ In some rare low-level cases, there are operations we perform that are
209
+ very similar to a node filesystem operation.
216
210
 
217
211
  For example, the `@vltpkg/which` module raises an error that is
218
- intentionally similar to node's filesystem `ENOENT` errors,
219
- because that is semantically sensible.
212
+ intentionally similar to node's filesystem `ENOENT` errors, because
213
+ that is semantically sensible.
220
214
 
221
- In those cases, the error _must_ follow node's conventions as
222
- close as possible. If we feel the need to add additional
223
- information beyond a known system error code, string path, etc.,
224
- or if the message isn't one that is typically raised by the
225
- underlying system, then it's a good sign that we ought to be
226
- creating an `Error` with a `cause` so that it can be reported
227
- more usefully.
215
+ In those cases, the error _must_ follow node's conventions as close as
216
+ possible. If we feel the need to add additional information beyond a
217
+ known system error code, string path, etc., or if the message isn't
218
+ one that is typically raised by the underlying system, then it's a
219
+ good sign that we ought to be creating an `Error` with a `cause` so
220
+ that it can be reported more usefully.
228
221
 
229
222
  In such cases, this is fine:
230
223
 
@@ -246,11 +239,11 @@ throw Object.assign(new Error('could not resolve'), {
246
239
  })
247
240
  ```
248
241
 
249
- **Do not** copy properties from a lower-level error or cause onto
250
- the new cause object. That is unnecessary, and obscures the
251
- origin of problems. Instead, just include the lower-level error
252
- as the `cause` property. If you already have a low-level error,
253
- you don't need to invent a synthetic one!
242
+ **Do not** copy properties from a lower-level error or cause onto the
243
+ new cause object. That is unnecessary, and obscures the origin of
244
+ problems. Instead, just include the lower-level error as the `cause`
245
+ property. If you already have a low-level error, you don't need to
246
+ invent a synthetic one!
254
247
 
255
248
  For example, do not do this:
256
249
 
@@ -280,8 +273,8 @@ try {
280
273
  ### Do not subclass `Error`.
281
274
 
282
275
  Just use the `Error` classes defined in the language. Additional
283
- information about error causes should be on the `cause` property,
284
- not implicit in the constructor type.
276
+ information about error causes should be on the `cause` property, not
277
+ implicit in the constructor type.
285
278
 
286
279
  I.e. do not do this:
287
280
 
@@ -308,33 +301,33 @@ throw error('Could not version', { version })
308
301
  All of these are optional. Additional fields may be used where
309
302
  appropriate, and should be added to this list over time.
310
303
 
311
- - `cause` - The `cause` field within a `cause` object should
312
- always be an `Error` object that was previously thrown. Note
313
- that the `cause` on an Error itself might _also_ be a
314
- previously thrown error, if no additional information could be
315
- usefully added beyond improving the message.
304
+ - `cause` - The `cause` field within a `cause` object should always be
305
+ an `Error` object that was previously thrown. Note that the `cause`
306
+ on an Error itself might _also_ be a previously thrown error, if no
307
+ additional information could be usefully added beyond improving the
308
+ message.
316
309
  - `name` - String. The name of something.
317
310
  - `offset` - Number. The offset in a Buffer or file where we are
318
311
  trying to read or write.
319
312
  - `registry` - String or URL. A package registry.
320
- - `code` - This must be a string if set, and should
321
- only be present if it's one of our creation, not a code raised
322
- on a system error. Eg, `ERESOLVE`, not `ENOENT`.
313
+ - `code` - This must be a string if set, and should only be present if
314
+ it's one of our creation, not a code raised on a system error. Eg,
315
+ `ERESOLVE`, not `ENOENT`.
323
316
  - `path` - The target of a file system operation.
324
317
  - `target` - path on disk that is being written or extracted to
325
- - `spec` - a `@vltpkg/spec.Spec` object relevant to the operation
326
- that failed.
327
- - `from` - string. The file path origin of a resolution that
328
- failed, for example in the case of relative `file:` specifiers.
329
- - `status` - Number or null. Either the exit code of a process or
330
- an HTTP response status code.
331
- - `signal` - `NodeJS.Signals` string or null, indicating the
332
- signal that terminated a process.
318
+ - `spec` - a `@vltpkg/spec.Spec` object relevant to the operation that
319
+ failed.
320
+ - `from` - string. The file path origin of a resolution that failed,
321
+ for example in the case of relative `file:` specifiers.
322
+ - `status` - Number or null. Either the exit code of a process or an
323
+ HTTP response status code.
324
+ - `signal` - `NodeJS.Signals` string or null, indicating the signal
325
+ that terminated a process.
333
326
  - `validOptions` - Array of valid options when something is not a
334
327
  valid option. (For use in `did you mean X?` output.)
335
- - `todo` - String message indicating what bit of work this might
336
- be a part of, what feature needs to be implemented, etc. Eg, `{
337
- todo: 'nested workspace support' }`.
328
+ - `todo` - String message indicating what bit of work this might be a
329
+ part of, what feature needs to be implemented, etc. Eg,
330
+ `{ todo: 'nested workspace support' }`.
338
331
  - `wanted` - A desired value that was not found, or a regular
339
332
  expression or other pattern describing it.
340
333
  - `found` - The actual value, which was not wanted.
@@ -354,9 +347,9 @@ todo: 'nested workspace support' }`.
354
347
 
355
348
  - If there is a _type_ problem with an argument, for example a
356
349
  `string` was expected and a `number` was provided, throw a
357
- `TypeError`. **Do not** use it for a value that is the correct
358
- type but otherwise invalid, such as a `string` argument that is
359
- actually a `string` but does not match an expected pattern.
350
+ `TypeError`. **Do not** use it for a value that is the correct type
351
+ but otherwise invalid, such as a `string` argument that is actually
352
+ a `string` but does not match an expected pattern.
360
353
  - If the type is fine, but a parsed string is invalid and not
361
354
  parseable, use `SyntaxError`.
362
355
  - In all other cases, use `Error`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vltpkg/error-cause",
3
3
  "description": "vlts Error.cause convention",
4
- "version": "0.0.0-3",
4
+ "version": "0.0.0-5",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",