Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickinson <christopher.s.dickinson@gmail.com>2015-02-10 23:48:55 +0300
committerChris Dickinson <christopher.s.dickinson@gmail.com>2015-02-11 04:58:10 +0300
commit7e2235aebb067b84974e001f9fa4d83f45b7c9dd (patch)
tree02a39a7cd65931e46a7ea0c8ed41b43ba88f3f89
parentd832be4aa3c68c29017339a65593f62cb73179bc (diff)
doc: add error documentation
PR-URL: https://github.com/iojs/io.js/pull/789 Reviewed-by: Rod Vagg <rod@vagg.org> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
-rw-r--r--doc/api/_toc.markdown1
-rw-r--r--doc/api/all.markdown1
-rw-r--r--doc/api/errors.markdown470
3 files changed, 472 insertions, 0 deletions
diff --git a/doc/api/_toc.markdown b/doc/api/_toc.markdown
index cf643e28cf9..c838ab383e2 100644
--- a/doc/api/_toc.markdown
+++ b/doc/api/_toc.markdown
@@ -12,6 +12,7 @@
* [Debugger](debugger.html)
* [DNS](dns.html)
* [Domain](domain.html)
+* [Errors](errors.html)
* [Events](events.html)
* [File System](fs.html)
* [Globals](globals.html)
diff --git a/doc/api/all.markdown b/doc/api/all.markdown
index 0f0ec6338d8..c01752feed7 100644
--- a/doc/api/all.markdown
+++ b/doc/api/all.markdown
@@ -11,6 +11,7 @@
@include dgram
@include dns
@include domain
+@include errors
@include events
@include fs
@include globals
diff --git a/doc/api/errors.markdown b/doc/api/errors.markdown
new file mode 100644
index 00000000000..92cae6d256d
--- /dev/null
+++ b/doc/api/errors.markdown
@@ -0,0 +1,470 @@
+# Errors
+
+<!--type=misc-->
+
+Errors generated by io.js fall into two categories: JavaScript errors and system
+errors. All errors inherit from or are instances of JavaScript's [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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](#errors_error_propagation_and_interception).
+
+## JavaScript Errors
+
+<!--type=misc-->
+
+JavaScript errors typically denote that an API is being used incorrectly, or that
+there is a problem with the program as written.
+
+### 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.
+
+**Note**: io.js will generate this class of error to encapsulate system
+errors as well as plain JavaScript errors.
+
+#### 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](https://code.google.com/p/v8-wiki/wiki/JavaScriptStackTraceApi).
+Stack traces only extend to the beginning of synchronous code execution, *or* a number of frames given by
+`Error.stackTraceLimit`, whichever is smaller.
+
+#### 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.
+
+#### 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:
+
+ Error: Things keep happening!
+ at /home/gbusey/file.js:525:2
+ at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
+ 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
+var 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 io.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 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).
+
+#### 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.
+
+```javascript
+var 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.
+
+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:
+
+```javascript
+
+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
+
+```
+
+#### Error.stackTraceLimit
+
+Property that determines the number of stack frames collected by a stack trace
+(whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`).
+
+The initial value is `10`. It may be set to any valid JavaScript number, which
+will effect 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.
+
+### 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:
+
+```javascript
+require('net').connect(-1); // throws RangeError, port should be > 0 && < 65536
+```
+
+io.js will generate and throw RangeError instances *immediately* -- they are a form
+of argument validation.
+
+### 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.
+
+```javascript
+require('url').parse(function() { }); // throws TypeError, since it expected a string
+```
+
+io.js will generate and throw TypeError instances *immediately* -- they are a form
+of argument validation.
+
+### 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.
+
+```javascript
+doesNotExist; // throws ReferenceError, doesNotExist is not a variable in this program.
+```
+
+ReferenceError instances will have an `.arguments` member that is an array containing
+one element -- a string representing the variable that was not defined.
+
+```javascript
+try {
+ doesNotExist;
+} catch(err) {
+ err.arguments[0] === 'doesNotExist';
+}
+```
+
+Unless the userland program is dynamically generating and running code,
+ReferenceErrors should always be considered a bug in the program, or its
+dependencies.
+
+### 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
+evaluation. Code evaluation may happen as a result of `eval`, `Function`,
+`require`, or [vm](vm.html). These errors are almost always indicative of a broken
+program.
+
+```javascript
+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.
+
+### 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 inherit from
+`Error`, all exceptions thrown by io.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.
+
+## 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` on most Unices;
+or [online](http://man7.org/linux/man-pages/man2/intro.2.html).
+
+In io.js, system errors are represented as augmented Error objects -- not full
+subclasses, but instead an error instance with added members.
+
+### Class: System Error
+
+#### error.syscall
+
+A string representing the [syscall](http://man7.org/linux/man-pages/man2/syscall.2.html) that failed.
+
+#### error.errno
+#### error.code
+
+A string representing the error code, which is always `E` followed by capital
+letters, and may be referenced in `man 2 intro`.
+
+### Common System Errors
+
+This list is **not exhaustive**, but enumerates many of the common system errors when
+writing a io.js program. An exhaustive list may be found [here](http://man7.org/linux/man-pages/man2/intro.2.html).
+
+#### EPERM: Operation not permitted
+
+An attempt was made to perform an operation that requires appropriate
+privileges.
+
+#### ENOENT: No such file or directory
+
+Commonly raised by [fs](fs.html) operations; a component of the specified pathname
+does not exist -- no entity (file or directory) could be found by the given path.
+
+#### EACCES: Permission denied
+
+An attempt was made to access a file in a way forbidden by its file access
+permissions.
+
+#### EEXIST: File exists
+
+An existing file was the target of an operation that required that the target
+not exist.
+
+#### ENOTDIR: Not a directory
+
+A component of the given pathname existed, but was not a directory as expected.
+Commonly raised by [fs.readdir](fs.html#fs_fs_readdir_path_callback).
+
+#### EISDIR: Is a directory
+
+An operation expected a file, but the given pathname was a directory.
+
+#### EMFILE: Too many open files in system
+
+Maxiumum number of [file descriptors](http://en.wikipedia.org/wiki/File_descriptor) 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
+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 io.js process.
+
+#### 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](net.html) and [http](http.html) layers, indicative that
+the remote side of the stream being written to has been closed.
+
+#### EADDRINUSE: Address already in use
+
+An attempt to bind a server ([net](net.html), [http](http.html), or [https](https.html)) to a local
+address failed due to another server on the local system already occupying
+that address.
+
+#### 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](http.html) and [net](net.html) modules.
+
+#### 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.
+
+#### ENOTEMPTY: Directory not empty
+
+A directory with entries was the target of an operation that requires
+an empty directory -- usually [fs.unlink](fs.html#fs_fs_unlink_path_callback).
+
+#### 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](http.html) or [net](net.html) --
+often a sign that a connected socket was not `.end()`'d appropriately.
+
+## Error Propagation and Interception
+
+<!--type=misc-->
+
+All io.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](fs.html#fs_fs_readfilesync_filename_options)) 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.
+
+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.
+
+### Node 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
+var 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', function(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:
+var fs = require('fs');
+
+try {
+ fs.readFile('/some/file/that/does-not-exist', function(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](domain.html) are enabled, they may intercept the thrown error; similarly, if a
+handler has been added to `process.on('uncaughtException')`, it will intercept
+the error.
+
+### Error events
+
+<!--type=misc-->
+
+The other mechanism for providing errors is the "error" event. This is
+typically used by [stream-based](stream.html) and [event emitter-based](events.html#events_class_events_eventemitter) 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](domain.html) are
+employed appropriately or [process.on('uncaughtException')](process.html#process_event_uncaughtexception) has a handler.
+
+```javascript
+var net = require('net');
+
+var connection = net.connect('localhost');
+
+// adding an "error" event handler to a stream:
+connection.on('error', function(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);
+});
+
+connection.pipe(process.stdout);
+```
+
+The "throw when no error handlers are attached behavior" is not limited to APIs
+provided by io.js -- even user created event emitters and streams will throw
+errors when no error handlers are attached. An example:
+
+```javascript
+var events = require('events');
+
+var ee = new events.EventEmitter;
+
+setImmediate(function() {
+ // this will crash the process because no "error" event
+ // handler has been added.
+ ee.emit('error', new Error('This will crash'));
+});
+```
+
+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.