I have joined writing middle-size multi-purpose database application as co-lead. It currently has about 150 tables (and growing) and overall functionality you can imagine as very small ERP.
At many places in code, functionalities which would normally belong into procedures (I mean functions without return value) like DeleteAttachment
or SaveRecord
are put into functions with return value reporting their exit status in string. They return either "OK"
on success or messages like "Deletion failed because ......."
or "Insufficient privileges for ......."
.
At the end, often the end user is presented with message they provided. On one hand, this is effective mechanism of tracing of potential problems. On the other hand, I’m not sure whether I should encourage this approach of writing the inner business logic.
I understand that putting non-fatal problems into exceptions is also not very good way to go (EInsufficientUserPrivileges
, ERecordAlreadyExists
). Should we stick with current approach or is there some other which is more suitable for applications using a many checks and business logic?
4
To draw the line between exceptions and return values, I would try to stick to the following:
– Anytime an instruction breaks the expected flow of execution, you expect an error to be thrown.
– If the expected function of procedure may have different outcomes, you will want to work with return values.
In the examples that you are stating, it seems very clearly that the expected instruction is not performed. Error messages like: “Deletion failed”, or “Insufficient privileges” end up with your action being void. Therefore, you would clearly expect an error to be thrown. In this context, fatal is equivalent to “your instruction could not be performed”. On the other hand, an exception does not necessarily have to be fatal. You may well handle it, and proceed with other instructions (other deletions, insertions, or whatever needs to be done). This is what you can achieve with a catch block.
Another thing: returning a string with “OK” is not good practice. Use boolean values instead. Now again, if you want return values to be “OK” or “Error message”, a boolean will not let you achieve that. An exception will let you put an error message, and any detail you want to store about the error that has happened. You could for example, if a user is denied access, store the user name, the priviledges that he has, and the record that he tried to access in an exception. You could then use this information as you catch the error to generate a short error message to the user, and a more detailed message for your error log.
15