Is it possible to throw a "RuntimeException" in Swift without declaring it?

To elaborate on Максим Мартынов's answer, Swift has 3 ways to do throw undeclared, uncatchable errors (but other approaches are possible if you want to venture outside Swift's standard library). These are based on the 3 levels of optimization:

  1. -Onone: No optimization; debug build
  2. -O: Normal optimization; release build
  3. -O SWIFT_DISABLE_SAFETY_CHECKS: Unchecked optimization; extremely optimized build

1. assertionFailure(_:)

Write this line when you're doing debugging tests and hit a line you don't think should ever be hit. These are removed in non-debug builds, so you must assume they will never be hit in the production app.

This has a sister function called assert(_:_:), which lets you assert at runtime whether a condition is true. assertionFailure(_:) is what you write when you know the situation is always bad, but don't think that'll harm the production code very much.

Usage:

if color.red > 0 {
    assertionFailure("The UI should have guaranteed the red level stays at 0")
    color = NSColor(red: 0, green: color.green, blue: color.blue)
}

2. preconditionFailure(_:)

Write this line when you're sure some condition you've described (in documentation, etc.) was not met. This works like assertionFailure(_:), but in release builds as well as debug ones.

Like assertionFailure(_:), this one's got a sister function called precondition(_:_:), which lets you decide at runtime whether a precondition was met. preconditionFailure(_:) is essentially that, but assuming the precondition is never met once the program gets to that line.

Usage:

guard index >= 0 else {
    preconditionFailure("You passed a negative number as an array index")
    return nil
}

Note that, in extremely optimized builds, it is not defined what happens if this line is hit! So if you don't want your app to wig out if it might ever hit this, then make sure the error state is handleable.

3. fatalError(_:)

Used as a last resort. When every other attempt to save the day has failed, here is your nuke. After printing the message you pass to it (along with the file and line number), the program stops dead in its tracks.

Once the program gets to this line, this line always runs, and the program never continues. This is true even in extremely optimized builds.

Usage:

#if arch(arm) || arch(arm64)
    fatalError("This app cannot run on this processor")
#endif

Further reading: Swift Assertions by Andy Bargh


Yes, it is possible!

Use: fatalError("your message here") to throw runtime exception