I see where you are coming from with having a status code returned to notify a problem exists. 

Personally, I'd calculate comissions in a seperate single responsibility class that extends an abstract class for interface segregation. That class implements three public methods: Calculate(), HasError(), GetError()

//calculate then commission: 

Set tCommission = tUsedCarCommission.Calculate()

If tUsedCarCommission.HasError() 

      //log the error or do something with it 


It's very similar to what you'd do with traditional status types but without having to deal with passing in references. Also, IMO, it's very clear what's going on if the commission has an error. 

We use various methods and macros to log exceptions, it just depends on the situation. 

I'm not really a fan of the status codes. They seem like a legacy item for the days prior to try/catches when traps were used. 

Having to maintain code to handle possible exceptions AND "errors" means more control flow to check and handle problems through the various levels of code.

Say that code above is within a method that's within another method that's called from the main part of the program. Now, you need three levels of try/catches. That's a lot of extra lines of code (code smell), lost errors and performance degradation.

Instead, I encourage my developers to use the fail fast methodgy. We use try/catches as high as possible in the code or when absolutely necessary, like when something is prone to exceptions but shouldn't stop the overall program from running.