Assertions and Exceptions

Illia Leshchuk
2 min readDec 27, 2021

Judging from my experience, the most common way of making assertions and throwing exceptions in apex code is the following:

if (!assertion)
{
throw new SomeException(message);
}

There is a built-in method System.assert but it throws only AssertException and even a bigger issue — it is uncatchable. So the solution is to built a custom and better assert method.

Phase I — initial implementation

An Exceptions class/namespace can be introduced with the following method:

public class Exceptions
{
public virtual class GenericException extends Exception {}
public class ArgumentException extends GenericException {}
public static Boolean assert(Boolean assertion, Exception e)
{
if (e == null)
{
throw new ArgumentException(Exceptions.class.getName() + '.assert(Boolean assertion, Exception e): ERROR: '
+ 'Argument e:Exception must not be null!');
}
else if (assertion != true)
{
throw e;
}

return assertion == true;
}
}

Now the initial code can be replaced with the following:

Exceptions.assert(assertion, new SomeException(message));

Phase II — optimization

At a glance look the code above and the initial code look the same, however there is a slight, yet sometimes significant difference — what if constructing a message for the exception is heavy and resource consuming process, e.g. a JSON serialization of a variable? This way the initial code has the advantage — resources are being consumed only in case of negative assertion, whereas call for Exception.assert above will consume resources every time. What we need is a solution which preserves the grace of the assert method and the efficiency of the initial code:

public class Exceptions
{
//may include all the code previously mentioned above

public static Boolean assert(Boolean assertion)
{
return assertion;
}

public static Boolean raise(Exception e)
{
throw e;
}
}

Now with the little help of magic and short-circuiting we can present the end result, which does exactly what we need:

Exceptions.assert(assertion || Exceptions.raise(new SomeException(message)));

UPDATE: Phase III— “safe-navigation operator” optimization

After introduction of safe-navigation operator it became possible to leverage it and it’s short-circuiting capabilities to make assertions even more lean and friendly

public class Exceptions
{
//may include all the code previously mentioned above
private Exceptions(){}

public static Exceptions whenever(Boolean assertion)
{
return (assertion == true ? new Exceptions() : null);
}

public static Exceptions unless(Boolean assertion)
{
return whenever(assertion == false);
}

public void raise(Exception e)
{
throw e;
}
}

And now making validation, assertion and other exception-related logic may look like this:

Exceptions.whenever(i == null)?.raise(new Exception('ERROR'));
Exceptions.unless(i != null)?.raise(new Exception('ERROR'));

--

--