Error Handling in Swift 2.0
===========================

As a tentpole feature for Swift 2.0, we are introducing a new
first-class error handling model.  This feature provides standardized
syntax and language affordances for throwing, propagating, catching,
and manipulating recoverable error conditions.

Error handling is a well-trod path, with many different approaches in
other languages, many of them problematic in various ways.  We believe
that our approach provides an elegant solution, drawing on the lessons
we've learned from other languages and fixing or avoiding some of the
pitfalls.  The result is expressive and concise while still feeling
explicit, safe, and familiar; and we believe it will work beautifully
with the Cocoa APIs.

We're intentionally not using the term "exception handling", which
carries a lot of connotations from its use in other languages.  Our
proposal has some similarities to the exceptions systems in those
languages, but it also has a lot of important differences.

Kinds of Error
--------------

What exactly is an "error"?  There are many possible error conditions,
and they don't all make sense to handle in exactly the same way,
because they arise in different circumstances and programmers have to
react to them differently.

We can break errors down into four categories, in increasing order of
severity:

A **simple domain error** arises from an operation that can fail in
some obvious way and which is often invoked speculatively.  Parsing an
integer from a string is a really good example.  The client doesn't
need a detailed description of the error and will usually want to
handle the error immediately.  These errors are already well-modeled
by returning an optional value; we don't need a more complex language
solution for them.

A **recoverable error** arises from an operation which can fail in
complex ways, but whose errors can be reasonably anticipated in
advance.  Examples including opening a file or reading from a network
connection.  These are the kinds of errors that Apple's APIs use
NSError for today, but there are close analogues in many other APIs,
such as ``errno`` in POSIX.

Ignoring this kind of error is usually a bad idea, and it can even be
dangerous (e.g. by introducing a security hole).  Developers should be
strongly encouraged to write code that handles the error.  It's common
for developers to want to handle errors from different operations in
the same basic way, either by reporting the error to the user or
passing the error back to their own clients.

These errors will be the focus of this proposal.

The final two classes of error are outside the scope of this proposal.
A **universal error** is theoretically recoverable, but by its nature
the language can't help the programmer anticipate where it will come
from.  A **logic failure** arises from a programmer mistake and should
not be recoverable at all.  In our system, these kinds of errors are
reported either with Objective-C/C++ exceptions or simply by
logging a message and calling ``abort()``.  Both kinds of error are
discussed extensively in the rationale.  Having considered them
carefully, we believe that we can address them in a later release
without significant harm.

Aspects of the Design
---------------------

This approach proposed here is very similar to the error handling
model manually implemented in Objective-C with the ``NSError``
convention.  Notably, the approach preserves these advantages of this
convention:

- Whether a method produces an error (or not) is an explicit part of
  its API contract.

- Methods default to *not* producing errors unless they are explicitly
  marked.
  
- The control flow within a function is still mostly explicit: a
  maintainer can tell exactly which statements can produce an error,
  and a simple inspection reveals how the function reacts to the
  error.
  
- Throwing an error provides similar performance to allocating an
  error and returning it -- it isn't an expensive, table-based stack
  unwinding process.
  
- Cocoa APIs using standard ``NSError`` patterns can be imported into
  this world automatically.  Other common patterns (e.g. ``CFError``,
  ``errno``) can be added to the model in future versions of Swift.

In addition, we feel that this design improves on Objective-C's error
handling approach in a number of ways:

- It eliminates a lot of boilerplate control-flow code for propagating
  errors.

- The syntax for error handling will feel familiar to people used to
  exception handling in other languages.

- Defining custom error types is simple and ties in elegantly with
  Swift enums.

As to basic syntax, we decided to stick with the familiar language of
exception handling.  We considered intentionally using different terms
(like ``raise`` / ``handle``) to try to distinguish our approach from
other languages.  However, by and large, error propagation in this
proposal works like it does in exception handling, and people are
inevitably going to make the connection.  Given that, we couldn't find
a compelling reason to deviate from the ``throw`` / ``catch`` legacy.

This document just contains the basic proposal and will be very
light on rationale.  We considered many different languages and
programming environments as part of making this proposal, and there's
an extensive discussion of them in the separate rationale document.
For example, that document explains why we don't simply allow all
functions to throw, why we don't propagate errors using simply an
``ErrorOr<T>`` return type, and why we don't just make error propagation
part of a general monad feature.  We encourage you to read that
rationale if you're interested in understanding why we made the
decisions we did.

With that out of the way, let's get to the details of the proposal.

Typed propagation
-----------------

Whether a function can throw is part of its type.  This applies to all
functions, whether they're global functions, methods, or closures.

By default, a function cannot throw.  The compiler statically enforces
this: anything the function does which can throw must appear in a
context which handles all errors.

A function can be declared to throw by writing ``throws`` on the
function declaration or type::

  func foo() -> Int {  // This function is not permitted to throw.
  func bar() throws -> Int {   // This function is permitted to throw.

``throws`` is written before the arrow to give a sensible and consistent
grammar for function types and implicit ``()`` result types, e.g.::

  func baz() throws {

  // Takes a 'callback' function that can throw.
  // 'fred' itself can also throw.
  func fred(_ callback: (UInt8) throws -> ()) throws {

  // These are distinct types.
  let a : () -> () -> ()
  let b : () throws -> () -> ()
  let c : () -> () throws -> ()
  let d : () throws -> () throws -> ()

For curried functions, ``throws`` only applies to the innermost
function.  This function has type ``(Int) -> (Int) throws -> Int``::

  func jerry(_ i: Int)(j: Int) throws -> Int {

``throws`` is tracked as part of the type system: a function value
must also declare whether it can throw.  Functions that cannot throw
are a subtype of functions that can, so you can use a function that
can't throw anywhere you could use a function that can::

  func rachel() -> Int { return 12 }
  func donna(_ generator: () throws -> Int) -> Int { ... }

  donna(rachel)

The reverse is not true, since the caller would not be prepared to
handle the error.

A call to a function which can throw within a context that is not
allowed to throw is rejected by the compiler.

It isn't possible to overload functions solely based on whether the
functions throw.  That is, this is not legal::

  func foo() { 
  func foo() throws {

A throwing method cannot override a non-throwing method or satisfy a
non-throwing protocol requirement.  However, a non-throwing method can
override a throwing method or satisfy a throwing protocol requirement.

It is valuable to be able to overload higher-order functions based on
whether an argument function throws, so this is allowed::

  func foo(_ callback: () throws -> Bool) {
  func foo(_ callback: () -> Bool) {

``rethrows``
~~~~~~~~~~~~

Functions which take a throwing function argument (including as an
autoclosure) can be marked as ``rethrows``::

  extension Array {
    func map<U>(_ fn: ElementType throws -> U) rethrows -> [U]
  }

It is an error if a function declared ``rethrows`` does not include a
throwing function in at least one of its parameter clauses.

``rethrows`` is identical to ``throws``, except that the function
promises to only throw if one of its argument functions throws.

More formally, a function is *rethrowing-only* for a function *f* if:

- it is a throwing function parameter of *f*,

- it is a non-throwing function, or

- it is implemented within *f* (i.e. it is either *f* or a function or
  closure defined therein) and it does not throw except by either:

  - calling a function that is rethrowing-only for *f* or

  - calling a function that is ``rethrows``, passing only functions
    that are rethrowing-only for *f*.

It is an error if a ``rethrows`` function is not rethrowing-only for
itself.

A ``rethrows`` function is considered to be a throwing function.
However, a direct call to a ``rethrows`` function is considered to not
throw if it is fully applied and none of the function arguments can
throw.  For example::

  // This call to map is considered not to throw because its
  // argument function does not throw.
  let absolutePaths = paths.map { "/" + $0 }

  // This call to map is considered to throw because its
  // argument function does throw.
  let streams = try absolutePaths.map { try InputStream(filename: $0) }

For now, ``rethrows`` is a property of declared functions, not of
function values.  Binding a variable (even a constant) to a function
loses the information that the function was ``rethrows``, and calls to
it will use the normal rules, meaning that they will be considered to
throw regardless of whether a non-throwing function is passed.

For the purposes of override and conformance checking, ``rethrows``
lies between ``throws`` and non-``throws``.  That is, an ordinary
throwing method cannot override a ``rethrows`` method, which cannot
override a non-throwing method; but an ordinary throwing method can be
overridden by a ``rethrows`` method, which can be overridden by a
non-throwing method.  Equivalent rules apply for protocol conformance.

Throwing an error
-----------------

The ``throw`` statement begins the propagation of an error.  It always
takes an argument, which can be any value that conforms to the
``Error`` protocol (described below).

::

  if timeElapsed > timeThreshold {
    throw HomeworkError.Overworked
  }

  throw NSError(domain: "whatever", code: 42, userInfo: nil)

As mentioned above, attempting to throw an error out of a function not
marked ``throws`` is a static compiler error.

Catching errors
---------------

A ``catch`` clause includes an optional pattern that matches the
error.  This pattern can use any of the standard pattern-matching
tools provided by ``switch`` statements in Swift, including boolean
``where`` conditions.  The pattern can be omitted; if so, a ``where``
condition is still permitted.  If the pattern is omitted, or if it
does not bind a different name to the error, the name ``error`` is
automatically bound to the error as if with a ``let`` pattern.

The ``try`` keyword is used for other purposes which it seems to fit far
better (see below), so ``catch`` clauses are instead attached to a
generalized ``do`` statement::

  // Simple do statement (without a trailing while condition),
  // just provides a scope for variables defined inside of it.
  do {
     let x = foo()
  }

  // do statement with two catch clauses.
  do {
    ...

  } catch HomeworkError.Overworked {
    // a conditionally-executed catch clause

  } catch _ {
    // a catch-all clause.  
  }

As with ``switch`` statements, Swift makes an effort to understand
whether catch clauses are exhaustive.  If it can determine it is, then
the compiler considers the error to be handled.  If not, the error
automatically propagates out of scope, either to a lexically
enclosing ``catch`` clause or out of the containing function (which must
be marked ``throws``).

We expect to refine the ``catch`` syntax with usage experience.

``Error``
-----------------

The Swift standard library will provide ``Error``, a protocol with
a very small interface (which is not described in this proposal).  The
standard pattern should be to define the conformance of an ``enum`` to
the type::

  enum HomeworkError : Error {
    case Overworked
    case Impossible
    case EatenByCat(Cat)
    case StopStressingMeWithYourRules
  }

The ``enum`` provides a namespace of errors, a list of possible errors
within that namespace, and optional values to attach to each option.

Note that this corresponds very cleanly to the ``NSError`` model of an
error domain, an error code, and optional user data.  We expect to
import system error domains as enums that follow this approach and
implement ``Error``.  ``NSError`` and ``CFError`` themselves will also
conform to ``Error``.

The physical representation (still being nailed down) will make it
efficient to embed an ``NSError`` as an ``Error`` and vice-versa.  It
should be possible to turn an arbitrary Swift ``enum`` that conforms to
``Error`` into an ``NSError`` by using the qualified type name as the
domain key, the enumerator as the error code, and turning the payload
into user data.

Automatic, marked, propagation of errors
----------------------------------------

Once an error is thrown, Swift will automatically propagate it out of
scopes (that permit it), rather than relying on the programmer to
manually check for errors and do their own control flow.  This is just
a lot less boilerplate for common error handling tasks.  However,
doing this naively would introduce a lot of implicit control flow,
which makes it difficult to reason about the function's behavior.
This is a serious maintenance problem and has traditionally been a
considerable source of bugs in languages that heavily use exceptions.

Therefore, while Swift automatically propagates errors, it requires
that statements and expressions that can implicitly throw be marked
with the ``try`` keyword.  For example::

  func readStuff() throws {
    // loadFile can throw an error.  If so, it propagates out of readStuff.
    try loadFile("mystuff.txt")

    // This is a semantic error; the 'try' keyword is required
    // to indicate that it can throw.
    var y = stream.readFloat()

    // This is okay; the try covers the entire statement.
    try y += stream.readFloat()

    // This try applies to readBool().
    if try stream.readBool() {
      // This try applies to both of these calls.
      let x = try stream.readInt() + stream.readInt()
    }

    if let err = stream.getOutOfBandError() {
      // Of course, the programmer doesn't have to mark explicit throws.
      throw err
    }
  }

Developers can choose to "scope" the ``try`` very tightly by writing it
within parentheses or on a specific argument or list element::

  // Ok.
  let x = (try stream.readInt()) + (try stream.readInt())

  // Semantic error: the try only covers the parenthesized expression.
  let x2 = (try stream.readInt()) + stream.readInt()

  // The try applies to the first array element.  Of course, the
  // developer could cover the entire array by writing the try outside.
  let array = [ try foo(), bar(), baz() ]

Some developers may wish to do this to make the specific throwing
calls very clear.  Other developers may be content with knowing that
something within a statement can throw. The compiler's fixit hints will
guide developers towards inserting a single ``try`` that covers the entire
statement.  This could potentially be controlled someday by a coding
style flag passed to the compiler.

``try!``
~~~~~~~~

To concisely indicate that a call is known to not actually throw at
runtime, ``try`` can be decorated with ``!``, turning the error check
into a runtime assertion that the call does not throw.

For the purposes of checking that all errors are handled, a ``try!``
expression is considered to handle any error originating from within
its operand.

``try!`` is otherwise exactly like ``try``: it can appear in exactly
the same positions and doesn't affect the type of an expression.

Manual propagation and manipulation of errors
---------------------------------------------

Taking control over the propagation of errors is important for some
advanced use cases (e.g. transporting an error result across threads
when synchronizing a future) and can be more convenient or natural for
specific use cases (e.g. handling a specific call differently within a
context that otherwise allows propagation).

As such, the Swift standard library should provide a standard
Rust-like ``Result<T>`` enum, along with API for working with it,
e.g.:

- A function to evaluate an error-producing closure and capture the
  result as a ``Result<T>``.

- A function to unpack a ``Result<T>`` by either returning its
  value or propagating the error in the current context.

This is something that composes on top of the basic model, but that
has not been designed yet and details aren't included in this
proposal.

The name ``Result<T>`` is a stand-in and needs to be designed and
reviewed, as well as the basic operations on the type.

``defer``
---------

Swift should provide a ``defer`` statement that sets up an *ad hoc*
clean-up action to be run when the current scope is exited.  This
replicates the functionality of a Java-style ``finally``, but more
cleanly and with less nesting.

This is an important tool for ensuring that explicitly-managed
resources are released on all paths.  Examples include closing a
network connection and freeing memory that was manually allocated.  It
is convenient for all kinds of error-handling, even manual propagation
and simple domain errors, but is especially nice with automatic
propagation.  It is also a crucial part of our long-term vision for
universal errors.

``defer`` may be followed by an arbitrary statement.  The compiler
should reject a ``defer`` action that might terminate early, whether by
throwing or with ``return``, ``break``, or ``continue``.

Example::

  if exists(filename) {
    let file = open(filename, O_READ)
    defer close(file)

    while let line = try file.readline() {
      ...
    }

    // close occurs here, at the end of the formal scope.
  }

If there are multiple defer statements in a scope, they are guaranteed
to be executed in reverse order of appearance.  That is::

  let file1 = open("hello.txt")
  defer close(file1)
  let file2 = open("world.txt")
  defer close(file2)
  ...
  // file2 will be closed first.

A potential extension is to provide a convenient way to mark that a
defer action should only be taken if an error is thrown.  This is a
convenient shorthand for controlling the action with a flag.  We will
evaluate whether adding complexity to handle this case is justified
based on real-world usage experience.

Importing Cocoa
---------------

If possible, Swift's error-handling model should transparently work
with the SDK with a minimal amount of effort from framework owners.

We believe that we can cover the vast majority of Objective-C APIs
with ``NSError**`` out-parameters by importing them as ``throws`` and
removing the error clause from their signature.  That is, a method
like this one from ``NSAttributedString``::

  - (NSData *)dataFromRange:(NSRange)range
         documentAttributes:(NSDictionary *)dict
                      error:(NSError **)error;

would be imported as::

  func dataFromRange(_ range: NSRange,
                     documentAttributes dict: NSDictionary) throws -> NSData

There are a number of cases to consider, but we expect that most can
be automatically imported without extra annotation in the SDK, by
using a couple of simple heuristics:

* The most common pattern is a ``BOOL`` result, where a false value
  means an error occurred.  This seems unambiguous.

* Also common is a pointer result, where a ``nil`` result usually
  means an error occurred.  This appears to be universal in
  Objective-C; APIs that can return ``nil`` results seem to do so via
  out-parameters.  So it seems to be safe to make a policy decision
  that it's okay to assume that a ``nil`` result is an error by
  default.

  If the pattern for a method is that a ``nil`` result means it produced
  an error, then the result can be imported as a non-optional type.

* A few APIs return ``void``.  As far as I can tell, for all of these,
  the caller is expected to check for a non-``nil`` error.

For other sentinel cases, we can consider adding a new clang attribute
to indicate to the compiler what the sentinel is:

* There are several APIs returning ``NSInteger`` or ``NSUInteger``.  At
  least some of these return 0 on error, but that doesn't seem like a
  reasonable general assumption.

* ``AVFoundation`` provides a couple methods returning
  ``AVKeyValueStatus``.  These produce an error if the API returned
  ``AVKeyValueStatusFailed``, which, interestingly enough, is not the
  zero value.

The clang attribute would specify how to test the return value for an
error.  For example::

  + (NSInteger)writePropertyList:(id)plist
                        toStream:(NSOutputStream *)stream
                          format:(NSPropertyListFormat)format
                         options:(NSPropertyListWriteOptions)opt
                           error:(out NSError **)error
    NS_ERROR_RESULT(0);

  - (AVKeyValueStatus)statusOfValueForKey:(NSString *)key
                                    error:(NSError **)
    NS_ERROR_RESULT(AVKeyValueStatusFailed);

We should also provide a Clang attribute which specifies that the
correct way to test for an error is to check the out-parameter.  Both
of these attributes could potentially be used by the static analyzer,
not just Swift.  (For example, they could try to detect an invalid
error check.)

Cases that do not match the automatically imported patterns and that
lack an attribute would be left unmodified (i.e., they'd keep their
NSErrorPointer argument) and considered "not awesome" in the SDK
auditing tool.  These will still be usable in Swift: callers will get
the NSError back like they do today, and have to throw the result
manually.

For initializers, importing an initializer as throwing takes
precedence over importing it as failable.  That is, an imported
initializer with a nullable result and an error parameter would be
imported as throwing.  Throwing initializers have very similar
constraints to failable initializers; in a way, it's just a new axis
of failability.

One limitation of this approach is that we need to be able to reconstruct
the selector to use when an overload of a method is introduced.  For this
reason, the import is likely to be limited to methods where the error
parameter is the last one and the corresponding selector
chunk is either ``error:`` or the first chunk (see below).  Empirically,
this seems to do the right thing for all but two sets of APIs in the
public API:

* The ``ISyncSessionDriverDelegate`` category on ``NSObject`` declares
  half-a-dozen methods like this::

    - (BOOL)sessionDriver:(ISyncSessionDriver *)sender
            didRegisterClientAndReturnError:(NSError **)outError;

  Fortunately, these delegate methods were all deprecated in Lion, and
  are thus unavailable in Swift.

* ``NSFileCoordinator`` has half a dozen methods where the ``error:``
  clause is second-to-last, followed by a block argument.  These
  methods are not deprecated as far as I know.

The above translation rule would import methods like this one from
``NSDocument``::

  - (NSDocument *)duplicateAndReturnError:(NSError **)outError;

like so::

  func duplicateAndReturnError() throws -> NSDocument

The ``AndReturnError`` bit is common but far from universal; consider
this method from ``NSManagedObject``::

  - (BOOL)validateForDelete:(NSError **)error;

This would be imported as::

  func validateForDelete() throws

This is a really nice import, and it's somewhat unfortunate that we
can't import ``duplicateAndReturnError:`` as ``duplicate()``.


Potential future extensions to this model
-----------------------------------------

We believe that the proposal above is sufficient to provide a huge
step forward in error handling in Swift programs, but there is always
more to consider in the future.  Some specific things we've discussed
(and may come back to in the future) but don't consider to be core to
the Swift 2.0 model are:

Higher-order polymorphism
~~~~~~~~~~~~~~~~~~~~~~~~~

We should make it easy to write higher-order functions that behave
polymorphically with respect to whether their arguments throw.  This
can be done in a fairly simple way: a function can declare that it
throws if any of a set of named arguments do.  As an example (using
strawman syntax)::

  func map<T, U>(_ array: [T], fn: T -> U) throwsIf(fn) -> [U] {
    ...
  }

There's no need for a more complex logical operator than disjunction
for normal higher-order stuff.

This feature is highly desired (e.g. it would allow many otherwise
redundant overloads to be collapsed into a single definition), but it
may or may not make it into Swift 2.0 based on schedule limitations.

Generic polymorphism
~~~~~~~~~~~~~~~~~~~~

For similar reasons to higher-order polymorphism, we should consider
making it easier to parameterize protocols on whether their operations
can throw.  This would allow the writing of generic algorithms, e.g.
over ``Sequence``, that handle both conformances that cannot throw (like
``Array``) and those that can (like a hypothetical cloud-backed
implementation).

However, this would be a very complex feature, yet to be designed, and
it is far out-of-scope for Swift 2.0.  In the meantime, most standard
protocols will be written to not allow throwing conformances, so as to
not burden the use of common generic algorithms with spurious
error-handling code.

Statement-like functions
~~~~~~~~~~~~~~~~~~~~~~~~

Some functions are designed to take trailing closures that feel like
sub-statements.  For example, ``autoreleasepool`` can be used this way::

  autoreleasepool {
    foo()
  }

The error-handling model doesn't cause major problems for this.  The
compiler can infer that the closure throws, and ``autoreleasepool``
can be overloaded on whether its argument closure throws; the
overload that takes a throwing closures would itself throw.

There is one minor usability problem here, though.  If the closure
contains throwing expressions, those expressions must be explicitly
marked within the closure with ``try``.  However, from the compiler's
perspective, the call to ``autoreleasepool`` is also a call that
can throw, and so it must also be marked with ``try``::

  try autoreleasepool {    // 'try' is required here...
    let string = try parseString() // ...and here.
    ...
  }

This marking feels redundant.  We want functions like
``autoreleasepool`` to feel like statements, but marks inside built-in
statements like ``if`` don't require the outer statement to be marked.
It would be better if the compiler didn't require the outer ``try``.

On the other hand, the "statement-like" story already has a number of
other holes: for example, ``break``, ``continue``, and ``return``
behave differently in the argument closure than in statements.  In the
future, we may consider fixing that; that fix will also need to
address the error-propagation problem.

``using``
~~~~~~~~~

A ``using`` statement would acquire a resource, holds it for a fixed
period of time, optionally binds it to a name, and then releases it
whenever the controlled statement exits.  ``using`` has many
similarities to ``defer``.  It does not subsume ``defer``, which is useful
for many ad-hoc and tokenless clean-ups.  But it could be convenient
for the common pattern of a type-directed clean-up.

Automatically importing CoreFoundation and C functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CF APIs use ``CFErrorRef`` pretty reliably, but there are several
problems here: 1) the memory management rules for CFErrors are unclear
and potentially inconsistent.  2) we need to know when an error is
raised.

In principle, we could import POSIX functions into Swift as throwing
functions, filling in the error from ``errno``.  It's nearly impossible
to imagine doing this with an automatic import rule, however; much
more likely, we'd need to wrap them all in an overlay.

In both cases, it is possible to pull these into the Swift error
handling model, but because this is likely to require massive SDK
annotations it is considered out of scope for iOS 9/OS X 10.11 & Swift 2.0.

Unexpected and universal errors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As discussed above, we believe that we can extend our current model to
support untyped propagation for universal errors.  Doing this well,
and in particular doing it without completely sacrificing code size
and performance, will take a significant amount of planning and
insight.  For this reason, it is considered well out of scope for
Swift 2.0.

