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