This is usually handled with guard clauses instead of nested or chained if
s:
if (! cond1)
throw error 1;
if (! cond2)
throw error 2;
perform action;
Note that this assumes that the function actually returns upon error, otherwise this will lead to faulty behaviour. However, this is recommended. In general, don’t try to resume an action in the face of errors, yield control to a higher level in your application’s logic as soon as possible.
In particular, the “print error” aspect should almost (?) always be disconnected from the actual logic – otherwise you are violating the single responsibility principle.
As a consequence, let your logic-performing function exit early when an error condition is detected, and let other functions take care of printing those errors.