doc: revise error.md introduction

PR-URL: https://github.com/nodejs/node/pull/48423
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Mestery <mestery@protonmail.com>
This commit is contained in:
Antoine du Hamel 2023-06-16 01:24:53 +02:00 committed by GitHub
parent d2dfdd654e
commit 64255b11bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -46,15 +46,35 @@ try {
```
Any use of the JavaScript `throw` mechanism will raise an exception that
_must_ be handled using `try…catch` or the Node.js process will exit
immediately.
_must_ be handled or the Node.js process will exit immediately.
With few exceptions, _Synchronous_ APIs (any blocking method that does not
accept a `callback` function, such as [`fs.readFileSync`][]), will use `throw`
to report errors.
return a {Promise} nor accept a `callback` function, such as
[`fs.readFileSync`][]), will use `throw` to report errors.
Errors that occur within _Asynchronous APIs_ may be reported in multiple ways:
* Some asynchronous methods returns a {Promise}, you should always take into
account that it might be rejected. See [`--unhandled-rejections`][] flag for
how the process will react to an unhandled promise rejection.
<!-- eslint-disable no-useless-return -->
```js
const fs = require('fs/promises');
(async () => {
let data;
try {
data = await fs.readFile('a file that does not exist');
} catch (err) {
console.error('There was an error reading the file!', err);
return;
}
// Otherwise handle the data
})();
```
* Most asynchronous methods that accept a `callback` function will accept an
`Error` object passed as the first argument to that function. If that first
argument is not `null` and is an instance of `Error`, then an error occurred
@ -104,9 +124,9 @@ pass or fail).
For _all_ [`EventEmitter`][] objects, if an `'error'` event handler is not
provided, the error will be thrown, causing the Node.js process to report an
uncaught exception and crash unless either: The [`domain`][domains] module is
used appropriately or a handler has been registered for the
[`'uncaughtException'`][] event.
uncaught exception and crash unless either: a handler has been registered for
the [`'uncaughtException'`][] event, or the deprecated [`node:domain`][domains]
module is used.
```js
const EventEmitter = require('node:events');
@ -125,60 +145,6 @@ they are thrown _after_ the calling code has already exited.
Developers must refer to the documentation for each method to determine
exactly how errors raised by those methods are propagated.
### Error-first callbacks
<!--type=misc-->
Most asynchronous methods exposed by the Node.js core API follow an idiomatic
pattern referred to as an _error-first callback_. With this pattern, a callback
function is passed to the method as an argument. When the operation either
completes or an error is raised, the callback function is called with the
`Error` object (if any) passed as the first argument. If no error was raised,
the first argument will be passed as `null`.
```js
const fs = require('node:fs');
function errorFirstCallback(err, data) {
if (err) {
console.error('There was an error', err);
return;
}
console.log(data);
}
fs.readFile('/some/file/that/does-not-exist', errorFirstCallback);
fs.readFile('/some/file/that/does-exist', errorFirstCallback);
```
The JavaScript `try…catch` mechanism **cannot** be used to intercept errors
generated by asynchronous APIs. A common mistake for beginners is to try to
use `throw` inside an error-first callback:
```js
// THIS WILL NOT WORK:
const fs = require('node:fs');
try {
fs.readFile('/some/file/that/does-not-exist', (err, data) => {
// Mistaken assumption: throwing here...
if (err) {
throw err;
}
});
} catch (err) {
// This will not catch the throw!
console.error(err);
}
```
This will not work because the callback function passed to `fs.readFile()` is
called asynchronously. By the time the callback has been called, the
surrounding code, including the `try…catch` block, will have already exited.
Throwing an error inside the callback **can crash the Node.js process** in most
cases. If [domains][] are enabled, or a handler has been registered with
`process.on('uncaughtException')`, such errors can be intercepted.
## Class: `Error`
<!--type=class-->
@ -3617,6 +3583,7 @@ The native call from `process.cpuUsage` could not be processed.
[`--disable-proto=throw`]: cli.md#--disable-protomode
[`--force-fips`]: cli.md#--force-fips
[`--no-addons`]: cli.md#--no-addons
[`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode
[`Class: assert.AssertionError`]: assert.md#class-assertassertionerror
[`ERR_INVALID_ARG_TYPE`]: #err_invalid_arg_type
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: #err_missing_message_port_in_transfer_list