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 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 _must_ be handled or the Node.js process will exit immediately.
immediately.
With few exceptions, _Synchronous_ APIs (any blocking method that does not With few exceptions, _Synchronous_ APIs (any blocking method that does not
accept a `callback` function, such as [`fs.readFileSync`][]), will use `throw` return a {Promise} nor accept a `callback` function, such as
to report errors. [`fs.readFileSync`][]), will use `throw` to report errors.
Errors that occur within _Asynchronous APIs_ may be reported in multiple ways: 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 * Most asynchronous methods that accept a `callback` function will accept an
`Error` object passed as the first argument to that function. If that first `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 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 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 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 uncaught exception and crash unless either: a handler has been registered for
used appropriately or a handler has been registered for the the [`'uncaughtException'`][] event, or the deprecated [`node:domain`][domains]
[`'uncaughtException'`][] event. module is used.
```js ```js
const EventEmitter = require('node:events'); 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 Developers must refer to the documentation for each method to determine
exactly how errors raised by those methods are propagated. 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` ## Class: `Error`
<!--type=class--> <!--type=class-->
@ -3617,6 +3583,7 @@ The native call from `process.cpuUsage` could not be processed.
[`--disable-proto=throw`]: cli.md#--disable-protomode [`--disable-proto=throw`]: cli.md#--disable-protomode
[`--force-fips`]: cli.md#--force-fips [`--force-fips`]: cli.md#--force-fips
[`--no-addons`]: cli.md#--no-addons [`--no-addons`]: cli.md#--no-addons
[`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode
[`Class: assert.AssertionError`]: assert.md#class-assertassertionerror [`Class: assert.AssertionError`]: assert.md#class-assertassertionerror
[`ERR_INVALID_ARG_TYPE`]: #err_invalid_arg_type [`ERR_INVALID_ARG_TYPE`]: #err_invalid_arg_type
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: #err_missing_message_port_in_transfer_list [`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: #err_missing_message_port_in_transfer_list