doc: improvements to errors.markdown copy
authorJames M Snell <jasnell@gmail.com>
Mon, 28 Dec 2015 19:42:05 +0000 (11:42 -0800)
committerMyles Borins <mborins@us.ibm.com>
Tue, 19 Jan 2016 19:52:34 +0000 (11:52 -0800)
General improvements to errors.markdown including
improved/revised examples

PR-URL: https://github.com/nodejs/node/pull/4454
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Minwoo Jung <jmwsoft@gmail.com>
doc/api/errors.markdown

index 8269e19..207c3b6 100644 (file)
 
 <!--type=misc-->
 
-Errors generated by Node.js fall into two categories: JavaScript errors and system
-errors. All errors inherit from or are instances of JavaScript's [`Error`][]
-class and are guaranteed to provide *at least* the attributes available on that
-class.
-
-When an operation is not permitted due to language-syntax or
-language-runtime-level reasons, a **JavaScript error** is generated and thrown
-as an **exception**. If an operation is not allowed due to system-level
-restrictions, a **system error** is generated. Client code is then given the
-opportunity to **intercept** this error based on how the API **propagates** it.
-
-The style of API called determines how generated errors are handed back, or
-**propagated**, to client code, which in turn informs how the client may **intercept**
-the error. Exceptions can be intercepted using the [`try / catch` construct][];
-other propagation strategies are covered [below][].
+Applications running in Node.js will generally experience four categories of
+errors:
+
+- Standard JavaScript errors such as:
+  - [`EvalError`][]: thrown when a call to `eval()` fails.
+  - [`SyntaxError`][]: thrown in response to improper JavaScript language
+    syntax.
+  - [`RangeError`][]: thrown when a value is not within an expected range
+  - [`ReferenceError`][]: thrown when using undefined variables
+  - [`TypeError`][]: thrown when passing arguments of the wrong type
+  - [`URIError`][]: thrown when a global URI handling function is misused.
+- System errors triggered by underlying operating system constraints such
+  as attempting to open a file that does not exist, attempting to send data
+  over a closed socket, etc;
+- And User-specified errors triggered by application code.
+- Assertion Errors are a special class of error that can be triggered whenever
+  Node.js detects an exceptional logic violation that should never occur. These
+  are raised typically by the `assert` module.
+
+All JavaScript and System errors raised by Node.js inherit from, or are
+instances of, the standard JavaScript [`Error`][] class and are guaranteed
+to provide *at least* the properties available on that class.
 
 ## Error Propagation and Interception
 
 <!--type=misc-->
 
-All Node.js APIs will treat invalid arguments as exceptional -- that is, if passed
-invalid arguments, they will *immediately* generate and throw the error as an
-exception, even if they are an otherwise asynchronous API.
-
-Synchronous APIs (like [`fs.readFileSync`][]) will throw the error. The act of
-*throwing* a value (in this case, the error) turns the value into an **exception**.
-Exceptions may be caught using the [`try { } catch(err) { }`][] construct.
+Node.js supports several mechanisms for propagating and handling errors that
+occur while an application is running. How these errors are reported and
+handled depends entirely on the type of Error and the style of the API that is
+called.
+
+All JavaScript errors are handled as exceptions that *immediately* generate
+and throw an error using the standard JavaScript `throw` mechanism. These
+are handled using the [`try / catch` construct][] provided by the JavaScript
+language.
+
+    // Throws with a ReferenceError because z is undefined
+    try {
+      const m = 1;
+      const n = m + z;
+    } catch (err) {
+      // Handle the error here.
+    }
 
-Asynchronous APIs have **two** mechanisms for error propagation; one mechanism
-for APIs that represent a single operation, and one for APIs that represent
-multiple operations over time.
+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.
 
-### Error events
+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.
 
-<!--type=misc-->
+Errors that occur within _Asynchronous APIs_ may be reported in multiple ways:
 
-The other mechanism for providing errors is the `'error'` event. This is
-typically used by [stream-based][] and [event emitter-based][] APIs, which
-themselves represent a series of asynchronous operations over time (versus a
-single operation that may pass or fail). If no `'error'` event handler is
-attached to the source of the error, the error will be thrown. At this point,
-it will crash the process as an unhandled exception unless [domains][] are
-employed appropriately or [`process.on('uncaughtException')`][] has a handler.
+- 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
+  that should be handled.
 
-```javascript
-const net = require('net');
+  ```
+  const fs = require('fs');
+  fs.readFile('a file that does not exist', (err, data) => {
+    if (err) {
+      console.error('There was an error reading the file!', err);
+      return;
+    }
+    // Otherwise handle the data
+  });
+  ```
+- When an asynchronous method is called on an object that is an `EventEmitter`,
+  errors can be routed to that object's `'error'` event.
+
+  ```
+  const net = require('net');
+  const connection = net.connect('localhost');
+
+  // Adding an 'error' event handler to a stream:
+  connection.on('error', (err) => {
+    // If the connection is reset by the server, or if it can't
+    // connect at all, or on any sort of error encountered by
+    // the connection, the error will be sent here.
+    console.error(err);
+  });
 
-const connection = net.connect('localhost');
+  connection.pipe(process.stdout);
+  ```
 
-// adding an 'error' event handler to a stream:
-connection.on('error', (err) => {
-  // if the connection is reset by the server, or if it can't
-  // connect at all, or on any sort of error encountered by
-  // the connection, the error will be sent here.
-  console.error(err);
-});
+- A handful of typically asynchronous methods in the Node.js API may still
+  use the `throw` mechanism to raise exceptions that must be handled using
+  `try / catch`. There is no comprehensive list of such methods; please
+  refer to the documentation of each method to determine the appropriate
+  error handling mechanism required.
 
-connection.pipe(process.stdout);
-```
+The use of the `'error'` event mechanism is most common for [stream-based][]
+and [event emitter-based][] APIs, which themselves represent a series of
+asynchronous operations over time (as opposed to a single operation that may
+pass or fail).
 
-The "throw when no error handlers are attached behavior" is not limited to APIs
-provided by Node.js -- even user created event emitters and streams will throw
-errors when no error handlers are attached. An example:
+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
+unhandled exception and  crash unless either: The [`domain`][] module is used
+appropriately or a handler has been registered for the
+[`process.on('uncaughtException')`][] event.
 
-```javascript
-const EventEmitter = require('events');
+    const EventEmitter = require('events');
+    const ee = new EventEmitter();
 
-const ee = new EventEmitter();
+    setImmediate(() => {
+      // This will crash the process because no 'error' event
+      // handler has been added.
+      ee.emit('error', new Error('This will crash'));
+    });
 
-setImmediate(() => {
-  // this will crash the process because no 'error' event
-  // handler has been added.
-  ee.emit('error', new Error('This will crash'));
-});
-```
+Errors generated in this way *cannot* be intercepted using `try / catch` as
+they are thrown *after* the calling code has already exited.
 
-As with node style callbacks, errors generated this way *cannot* be intercepted
-by `try { } catch(err) { }` -- they happen *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.
 
-### Node style callbacks
+### Node.js style callbacks
 
 <!--type=misc-->
 
-Single operation APIs take "node style callbacks" -- a
-function provided to the API as an argument. The node style callback takes
-at least **one** argument -- `error` -- that will either be `null` (if no error
-was encountered) or an `Error` instance.  For instance:
-
-```javascript
-const fs = require('fs');
-
-fs.readFile('/some/file/that/does-not-exist', function nodeStyleCallback(err, data) {
-  console.log(err)  // Error: ENOENT
-  console.log(data) // undefined / null
-});
-
-fs.readFile('/some/file/that/does-exist', (err, data) => {
-  console.log(err)  // null
-  console.log(data) // <Buffer: ba dd ca fe>
-})
-```
-
-Note that `try { } catch(err) { }` **cannot** intercept errors generated by
-asynchronous APIs. A common mistake for beginners is to try to use `throw`
-inside their node style callback:
-
-```javascript
-// THIS WILL NOT WORK:
-const fs = require('fs');
-
-try {
-  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
-    // mistaken assumption: throwing here...
-    if (err) {
-      throw err;
+Most asynchronous methods exposed by the Node.js core API follow an idiomatic
+pattern  referred to as a "Node.js style 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`.
+
+    const fs = require('fs');
+
+    function nodeStyleCallback(err, data) {
+     if (err) {
+       console.error('There was an error', err);
+       return;
+     }
+     console.log(data);
     }
-  });
-} catch(err) {
-  // ... will be caught here -- this is incorrect!
-  console.log(err); // Error: ENOENT
-}
-```
-
-This will not work! By the time the node style callback has been called, the
-surrounding code (including the `try { } catch(err) { }` will have already
-exited. Throwing an error inside a node style callback **will crash the process** in most cases.
-If [domains][] are enabled, they may intercept the thrown error; similarly, if a
-handler has been added to `process.on('uncaughtException')`, it will intercept
-the error.
 
-## JavaScript Errors
-
-<!--type=misc-->
+    fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);
+    fs.readFile('/some/file/that/does-exist', nodeStyleCallback)
+
+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 a Node.js style callback:
+
+    // THIS WILL NOT WORK:
+    const fs = require('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.log(err);
+    }
 
-JavaScript errors typically denote that an API is being used incorrectly, or that
-there is a problem with the program as written.
+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(err) { }` 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-->
 
-A general error object. Unlike other error objects, `Error` instances do not
-denote any specific circumstance of why the error occurred. Errors capture a
-"stack trace" detailing the point in the program at which they were
-instantiated, and may provide a description of the error.
+A generic JavaScript `Error` object that does not denote any specific
+circumstance of why the error occurred. `Error` objects capture a "stack trace"
+detailing the point in the code at which the `Error` was instantiated, and may
+provide a text description of the error.
 
-**Note**: Node.js will generate this class of error to encapsulate system
-errors as well as plain JavaScript errors.
+All errors generated by Node.js, including all System and JavaScript errors,
+will either be instances of, or inherit from, the `Error` class.
 
-#### new Error(message)
+### new Error(message)
 
-Instantiates a new `Error` object and sets its `.message` property to the provided
-message. Its `.stack` will represent the point in the program at which `new Error`
-was called. Stack traces are subject to [V8's stack trace API][].
-Stack traces only extend to the beginning of synchronous code execution, *or* a number of frames given by
-`Error.stackTraceLimit`, whichever is smaller.
+Creates a new `Error` object and sets the `error.message` property to the
+provided text message. If an object is passed as `message`, the text message
+is generated by calling `message.toString()`. The `error.stack` property will
+represent the point in the code at which `new Error()` was called. Stack traces
+are dependent on [V8's stack trace API][]. Stack traces extend only to either
+(a) the beginning of  *synchronous code execution*, or (b) the number of frames
+given by the property `Error.stackTraceLimit`, whichever is smaller.
 
-#### Error.captureStackTrace(targetObject[, constructorOpt])
+### Error.captureStackTrace(targetObject[, constructorOpt])
 
 Creates a `.stack` property on `targetObject`, which when accessed returns
-a string representing the location in the program at which `Error.captureStackTrace`
-was called.
+a string representing the location in the code at which
+`Error.captureStackTrace()` was called.
 
-```javascript
-var myObject = {};
-
-Error.captureStackTrace(myObject);
-
-myObject.stack  // similar to `new Error().stack`
-```
+    const myObject = {};
+    Error.captureStackTrace(myObject);
+    myObject.stack  // similar to `new Error().stack`
 
 The first line of the trace, instead of being prefixed with `ErrorType:
-message`, will be the result of `targetObject.toString()`.
-
-`constructorOpt` optionally accepts a function. If given, all frames above
-`constructorOpt`, including `constructorOpt`, will be omitted from the generated
-stack trace.
+message`, will be the result of calling `targetObject.toString()`.
 
-This is useful for hiding implementation details of error generation from the
-end user. A common way of using this parameter is to pass the current Error
-constructor to it:
+The optional `constructorOpt` argument accepts a function. If given, all frames
+above `constructorOpt`, including `constructorOpt`, will be omitted from the
+generated stack trace.
 
-```javascript
+The `constructorOpt` argument is useful for hiding implementation
+details of error generation from an end user. For instance:
 
-function MyError() {
-  Error.captureStackTrace(this, MyError);
-}
+    function MyError() {
+      Error.captureStackTrace(this, MyError);
+    }
 
-// without passing MyError to captureStackTrace, the MyError
-// frame would should up in the .stack property. by passing
-// the constructor, we omit that frame and all frames above it.
-new MyError().stack
+    // Without passing MyError to captureStackTrace, the MyError
+    // frame would should up in the .stack property. by passing
+    // the constructor, we omit that frame and all frames above it.
+    new MyError().stack
 
-```
+### Error.stackTraceLimit
 
-#### Error.stackTraceLimit
+The `Error.stackTraceLimit` property specifies the number of stack frames
+collected by a stack trace (whether generated by `new Error().stack` or
+`Error.captureStackTrace(obj)`).
 
-Property that determines the number of stack frames collected by a stack trace
-(whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`).
+The default value is `10` but may be set to any valid JavaScript number. Changes
+will affect any stack trace captured *after* the value has been changed.
 
-The initial value is `10`. It may be set to any valid JavaScript number, which
-will affect any stack trace captured *after* the value has been changed. If set
-to a non-number value, stack traces will not capture any frames and will report
-`undefined` on access.
+If set to a non-number value, or set to a negative number, stack traces will
+not capture any frames.
 
 #### error.message
 
-A string of the value passed to `Error()` upon instantiation. The message will
-also appear in the first line of the stack trace of the error. Changing this
-property *may not* change the first line of the stack trace.
+Returns the string description of error as set by calling `new Error(message)`.
+The `message` passed to the constructor will also appear in the first line of
+the stack trace of the `Error`, however changing this property after the
+`Error` object is created *may not* change the first line of the stack trace.
+
+    const err = new Error('The message');
+    console.log(err.message);
+      // Prints: The message
 
 #### error.stack
 
-A property that, when **accessed**, returns a string representing the point in the program
-at which this error was instantiated. An example stacktrace follows:
+Returns a string describing the point in the code at which the `Error` was
+instantiated.
+
+For example:
 
     Error: Things keep happening!
        at /home/gbusey/file.js:525:2
@@ -225,103 +260,107 @@ at which this error was instantiated. An example stacktrace follows:
        at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
        at increaseSynergy (/home/gbusey/actors.js:701:6)
 
-The first line is formatted as `<error class name>: <error message>`, and it is followed
-by a series of stack frames (each line beginning with "at "). Each frame describes
-a call site in the program that lead to the error being generated. V8 attempts to
-display a name for each function (by variable name, function name, or object
-method name), but occasionally it will not be able to find a suitable name. If
-V8 cannot determine a name for the function, only location information will be
-displayed for that frame. Otherwise, the determined function name will be displayed
-with location information appended in parentheses.
-
-Frames are **only** generated for JavaScript functions. If, for example, execution
-synchronously passes through a C++ addon function called `cheetahify`, which itself
-calls a JavaScript function, the frame representing the `cheetahify` call will **not**
-be present in stacktraces:
-
-```javascript
-const cheetahify = require('./native-binding.node');
-
-function makeFaster() {
-  // cheetahify *synchronously* calls speedy.
-  cheetahify(function speedy() {
-    throw new Error('oh no!');
-  });
-}
-
-makeFaster(); // will throw:
-// /home/gbusey/file.js:6
-//     throw new Error('oh no!');
-//           ^
-// Error: oh no!
-//     at speedy (/home/gbusey/file.js:6:11)
-//     at makeFaster (/home/gbusey/file.js:5:3)
-//     at Object.<anonymous> (/home/gbusey/file.js:10:1)
-//     at Module._compile (module.js:456:26)
-//     at Object.Module._extensions..js (module.js:474:10)
-//     at Module.load (module.js:356:32)
-//     at Function.Module._load (module.js:312:12)
-//     at Function.Module.runMain (module.js:497:10)
-//     at startup (node.js:119:16)
-//     at node.js:906:3
-```
+The first line is formatted as `<error class name>: <error message>`, and
+is followed by a series of stack frames (each line beginning with "at ").
+Each frame describes a call site within the code that lead to the error being
+generated. V8 attempts to display a name for each function (by variable name,
+function name, or object method name), but occasionally it will not be able to
+find a suitable name. If V8 cannot determine a name for the function, only
+location information will be displayed for that frame. Otherwise, the
+determined function name will be displayed with location information appended
+in parentheses.
+
+It is important to note that frames are **only** generated for JavaScript
+functions. If, for example, execution synchronously passes through a C++ addon
+function called `cheetahify`, which itself calls a JavaScript function, the
+frame representing the `cheetahify` call will **not** be present in the stack
+traces:
+
+    const cheetahify = require('./native-binding.node');
+
+    function makeFaster() {
+      // cheetahify *synchronously* calls speedy.
+      cheetahify(function speedy() {
+        throw new Error('oh no!');
+      });
+    }
+
+    makeFaster(); // will throw:
+      // /home/gbusey/file.js:6
+      //     throw new Error('oh no!');
+      //           ^
+      // Error: oh no!
+      //     at speedy (/home/gbusey/file.js:6:11)
+      //     at makeFaster (/home/gbusey/file.js:5:3)
+      //     at Object.<anonymous> (/home/gbusey/file.js:10:1)
+      //     at Module._compile (module.js:456:26)
+      //     at Object.Module._extensions..js (module.js:474:10)
+      //     at Module.load (module.js:356:32)
+      //     at Function.Module._load (module.js:312:12)
+      //     at Function.Module.runMain (module.js:497:10)
+      //     at startup (node.js:119:16)
+      //     at node.js:906:3
 
 The location information will be one of:
 
 * `native`, if the frame represents a call internal to V8 (as in `[].forEach`).
-* `plain-filename.js:line:column`, if the frame represents a call internal to Node.js.
-* `/absolute/path/to/file.js:line:column`, if the frame represents a call in a user program, or its dependencies.
+* `plain-filename.js:line:column`, if the frame represents a call internal
+   to Node.js.
+* `/absolute/path/to/file.js:line:column`, if the frame represents a call in
+  a user program, or its dependencies.
 
-It is important to note that the string representing the stacktrace is only
-generated on **access**: it is lazily generated.
+The string representing the stack trace is lazily generated when the
+`error.stack` property is **accessed**.
 
 The number of frames captured by the stack trace is bounded by the smaller of
 `Error.stackTraceLimit` or the number of available frames on the current event
 loop tick.
 
-System-level errors are generated as augmented `Error` instances, which are detailed
-[below](#errors_system_errors).
+System-level errors are generated as augmented `Error` instances, which are
+detailed [below](#errors_system_errors).
 
-### Class: RangeError
+## Class: RangeError
 
 A subclass of `Error` that indicates that a provided argument was not within the
-set or range of acceptable values for a function; whether that be a numeric
-range, or outside the set of options for a given function parameter. An example:
+set or range of acceptable values for a function; whether that is a numeric
+range, or outside the set of options for a given function parameter.
+
+For example:
 
-```javascript
-require('net').connect(-1);  // throws RangeError, port should be > 0 && < 65536
-```
+    require('net').connect(-1);
+      // throws RangeError, port should be > 0 && < 65536
 
-Node.js will generate and throw `RangeError` instances *immediately* -- they are a form
+Node.js will generate and throw `RangeError` instances *immediately* as a form
 of argument validation.
 
-### Class: ReferenceError
+## Class: ReferenceError
 
-A subclass of `Error` that indicates that an attempt is being made to access a variable
-that is not defined. Most commonly it indicates a typo, or an otherwise broken program.
-While client code may generate and propagate these errors, in practice only V8 will do
-so.
+A subclass of `Error` that indicates that an attempt is being made to access a
+variable that is not defined. Such errors commonly indicate typos in code, or
+an otherwise broken program.
 
-```javascript
-doesNotExist; // throws ReferenceError, doesNotExist is not a variable in this program.
-```
+While client code may generate and propagate these errors, in practice, only V8
+will do so.
 
-`ReferenceError` instances will have an `.arguments` member that is an array containing
-one element -- a string representing the variable that was not defined.
+    doesNotExist;
+      // throws ReferenceError, doesNotExist is not a variable in this program.
 
-```javascript
-try {
-  doesNotExist;
-} catch(err) {
-  err.arguments[0] === 'doesNotExist';
-}
-```
+`ReferenceError` instances will have an `error.arguments` property whose value
+is an array containing a single element: a string representing the variable
+that was not defined.
 
-Unless the userland program is dynamically generating and running code,
-ReferenceErrors should always be considered a bug in the program, or its
-dependencies.
+    const assert = require('assert');
+    try {
+      doesNotExist;
+    } catch(err) {
+      assert(err.arguments[0], 'doesNotExist');
+    }
+
+Unless an application is dynamically generating and running code,
+`ReferenceError` instances should always be considered a bug in the code
+or its dependencies.
 
-### Class: SyntaxError
+## Class: SyntaxError
 
 A subclass of `Error` that indicates that a program is not valid JavaScript.
 These errors may only be generated and propagated as a result of code
@@ -329,144 +368,129 @@ evaluation. Code evaluation may happen as a result of `eval`, `Function`,
 `require`, or [vm][]. These errors are almost always indicative of a broken
 program.
 
-```javascript
-try {
-  require('vm').runInThisContext('binary ! isNotOk');
-} catch(err) {
-  // err will be a SyntaxError
-}
-```
+    try {
+      require('vm').runInThisContext('binary ! isNotOk');
+    } catch(err) {
+      // err will be a SyntaxError
+    }
 
-SyntaxErrors are unrecoverable from the context that created them – they may only be caught
-by other contexts.
+`SyntaxError` instances are unrecoverable in the context that created them –
+they may only be caught by other contexts.
 
-### Class: TypeError
+## Class: TypeError
 
-A subclass of `Error` that indicates that a provided argument is not an allowable
-type. For example, passing a function to a parameter which expects a string would
-be considered a TypeError.
+A subclass of `Error` that indicates that a provided argument is not an
+allowable type. For example, passing a function to a parameter which expects a
+string would be considered a TypeError.
 
-```javascript
-require('url').parse(function() { }); // throws TypeError, since it expected a string
-```
+    require('url').parse(function() { });
+      // throws TypeError, since it expected a string
 
-Node.js will generate and throw `TypeError` instances *immediately* -- they are a form
+Node.js will generate and throw `TypeError` instances *immediately* as a form
 of argument validation.
 
-### Exceptions vs. Errors
+## Exceptions vs. Errors
 
 <!--type=misc-->
 
-A JavaScript exception is a value that is thrown as a result of an invalid operation or
-as the target of a `throw` statement. While it is not required that these values are instances of
-`Error` or classes which inherit from `Error`, all exceptions thrown by Node.js or the JavaScript
-runtime *will* be instances of Error.
+A JavaScript exception is a value that is thrown as a result of an invalid
+operation or as the target of a `throw` statement. While it is not required
+that these values are instances of `Error` or classes which inherit from
+`Error`, all exceptions thrown by Node.js or the JavaScript runtime *will* be
+instances of Error.
 
-Some exceptions are *unrecoverable* at the JavaScript layer. These exceptions will always bring
-down the process. These are usually failed `assert()` checks or `abort()` calls in the C++ layer.
+Some exceptions are *unrecoverable* at the JavaScript layer. Such exceptions
+will *always* cause the Node.js process to crash. Examples include `assert()`
+checks or `abort()` calls in the C++ layer.
 
 ## System Errors
 
-System errors are generated in response to a program's runtime environment.
-Ideally, they represent operational errors that the program needs to be able to
-react to. They are generated at the syscall level: an exhaustive list of error
-codes and their meanings is available by running `man 2 intro` or `man 3 errno`
-on most Unices; or [online][].
+System errors are generated when exceptions occur within the program's
+runtime environment. Typically, these are operational errors that occur
+when an application violates an operating system constraint such as attempting
+to read a file that does not exist or when the user does not have sufficient
+permissions.
+
+System errors are typically generated at the syscall level: an exhaustive list
+of error codes and their meanings is available by running `man 2 intro` or
+`man 3 errno` on most Unices; or [online][].
 
-In Node.js, system errors are represented as augmented `Error` objects -- not full
-subclasses, but instead an error instance with added members.
+In Node.js, system errors are represented as augmented `Error` objects with
+added properties.
 
 ### Class: System Error
 
 #### error.code
 #### error.errno
 
-A string representing the error code, which is always `E` followed by capital
-letters, and may be referenced in `man 2 intro`.
+Returns a string representing the error code, which is always `E` followed by
+a sequence of capital letters, and may be referenced in `man 2 intro`.
+
+The properties `error.code` and `error.errno` are aliases of one another and
+return the same value.
 
 #### error.syscall
 
-A string representing the [syscall][] that failed.
+Returns a string describing the [syscall][] that failed.
 
 ### Common System Errors
 
-This list is **not exhaustive**, but enumerates many of the common system errors when
-writing a Node.js program. An exhaustive list may be found [here][online].
-
-#### EACCES: Permission denied
-
-An attempt was made to access a file in a way forbidden by its file access
-permissions.
-
-#### EADDRINUSE: Address already in use
-
-An attempt to bind a server ([`net`][], [`http`][], or [`https`][]) to a local
-address failed due to another server on the local system already occupying
-that address.
-
-#### ECONNREFUSED: Connection refused
-
-No connection could be made because the target machine actively refused
-it. This usually results from trying to connect to a service that is inactive
-on the foreign host.
-
-#### ECONNRESET: Connection reset by peer
-
-A connection was forcibly closed by a peer. This normally results
-from a loss of the connection on the remote socket due to a timeout
-or reboot. Commonly encountered via the [`http`][] and [`net`][] modules.
-
-#### EEXIST: File exists
-
-An existing file was the target of an operation that required that the target
-not exist.
-
-#### EISDIR: Is a directory
-
-An operation expected a file, but the given pathname was a directory.
-
-#### EMFILE: Too many open files in system
-
-Maximum number of [file descriptors][] allowable on the system has
-been reached, and requests for another descriptor cannot be fulfilled until
-at least one has been closed.
+This list is **not exhaustive**, but enumerates many of the common system
+errors encountered when writing a Node.js program. An exhaustive list may be
+found [here][online].
 
-Commonly encountered when opening many files at once in parallel, especially
-on systems (in particular, OS X) where there is a low file descriptor limit
-for processes. To remedy a low limit, run `ulimit -n 2048` in the same shell
-that will run the Node.js process.
+- `EACCES` (Permission denied): An attempt was made to access a file in a way
+  forbidden by its file access permissions.
 
-#### ENOENT: No such file or directory
+- `EADDRINUSE` (Address already in use):  An attempt to bind a server
+  ([`net`][], [`http`][], or [`https`][]) to a local address failed due to
+  another server on the local system already occupying that address.
 
-Commonly raised by [`fs`][] operations; a component of the specified pathname
-does not exist -- no entity (file or directory) could be found by the given path.
+- `ECONNREFUSED` (Connection refused): No connection could be made because the
+  target machine actively refused it. This usually results from trying to
+  connect to a service that is inactive on the foreign host.
 
-#### ENOTDIR: Not a directory
+- `ECONNRESET` (Connection reset by peer): A connection was forcibly closed by
+  a peer. This normally results from a loss of the connection on the remote
+  socket due to a timeout or reboot. Commonly encountered via the [`http`][]
+  and [`net`][] modules.
 
-A component of the given pathname existed, but was not a directory as expected.
-Commonly raised by [`fs.readdir`][].
+- `EEXIST` (File exists): An existing file was the target of an operation that
+  required that the target not exist.
 
-#### ENOTEMPTY: Directory not empty
+- `EISDIR` (Is a directory): An operation expected a file, but the given
+  pathname was a directory.
 
-A directory with entries was the target of an operation that requires
-an empty directory -- usually [`fs.unlink`][].
+- `EMFILE` (Too many open files in system): Maximum number of
+  [file descriptors][] allowable on the system has been reached, and
+  requests for another descriptor cannot be fulfilled until at least one
+  has been closed. This is encountered when opening many files at once in
+  parallel, especially on systems (in particular, OS X) where there is a low
+  file descriptor limit for processes. To remedy a low limit, run
+  `ulimit -n 2048` in the same shell that will run the Node.js process.
 
-#### EPERM: Operation not permitted
+- `ENOENT` (No such file or directory): Commonly raised by [`fs`][] operations
+  to indicate that a component of the specified pathname does not exist -- no
+  entity (file or directory) could be found by the given path.
 
-An attempt was made to perform an operation that requires appropriate
-privileges.
+- `ENOTDIR` (Not a directory): A component of the given pathname existed, but
+  was not a directory as expected. Commonly raised by [`fs.readdir`][].
 
-#### EPIPE: Broken pipe
+- `ENOTEMPTY` (Directory not empty): A directory with entries was the target
+  of an operation that requires an empty directory -- usually [`fs.unlink`][].
 
-A write on a pipe, socket, or FIFO for which there is no process to read the
-data. Commonly encountered at the [`net`][] and [`http`][] layers, indicative that
-the remote side of the stream being written to has been closed.
+- `EPERM` (Operation not permitted): An attempt was made to perform an
+  operation that requires elevated privileges.
 
-#### ETIMEDOUT: Operation timed out
+- `EPIPE` (Broken pipe): A write on a pipe, socket, or FIFO for which there is
+  no process to read the data. Commonly encountered at the [`net`][] and
+  [`http`][] layers, indicative that the remote side of the stream being
+  written to has been closed.
 
-A connect or send request failed because the connected party did not properly
-respond after a period of time. Usually encountered by [`http`][] or [`net`][] --
-often a sign that a connected socket was not `.end()`'d appropriately.
+- `ETIMEDOUT` (Operation timed out): A connect or send request failed because
+  the connected party did not properly respond after a period of time. Usually
+  encountered by [`http`][] or [`net`][] -- often a sign that a `socket.end()`
+  was not properly called.
 
 [`Error`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
 [`fs.readdir`]: fs.html#fs_fs_readdir_path_callback
@@ -488,3 +512,7 @@ often a sign that a connected socket was not `.end()`'d appropriately.
 [syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html
 [V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API
 [vm]: vm.html
+[`SyntaxError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError
+[`ReferenceError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
+[`TypeError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
+[`domain`]: domain.html