Defensive Programming - Crashing Early

I try to always fail hard during development. When errors occur I want them to be loud and stop me dead in my tracks. This forces me to deal with edge cases and unexpected issues right away since they affect the development flow. The more I encounter, the more I fix, and the more predictable my software becomes.

Using assertions

One way to fail loud and hard during development is to use assertions. Every language I have used has an assert function built-in. These will typically halt execution and throw an error when the assertion is false.

For example in Kotlin I might write something like the following.

assert(count > 0) { 
	"Count should be greater than 0 but is $count" 
}

It is important to note that assertions in different languages may not be enabled by default. In the case of the JVM you need to enable it on the process with the -ea flag.

In Swift assertions are on by default and you can read a great overview of assert and the other handy assert-like functions here.

In Swift I often use this to check the current thread to ensure my callbacks are all running on the main thread.

doSomeWork { 
	assert(Thread.isMainThread)
	//update ui
}

Note that assertions in Swift are optimized out in release mode.

Fail early. Fail often. Fail hard. Make better software.