Handling "Exceptions" that have a high probability of becoming "Errors"
In the project i'm currently working on, I am having a bit of trouble distinguishing Errors from Exceptions (to add to the confusion I'm not sure if my definition of Error and Exception are fully correct either).
The place I'm getting confused is how to stop an exception from becoming an error. Say I have a model class that holds a bunch of relationships. The model has a Model.AddRelationship()
method that has the potential to create a circular reference in the model. If the user tries to add a relationship in the UI that creates a circular reference, they must be blocked from doing so and told why. So I've grappled with some options such as:
// In the UI when the user tries to add a relationship:
var newRelationship:Relationship = new Relationship();
if(Model.AddingThisWillCreateACircularReference(newRelationship))
{
this.warnUserAboutCircularReference();
}
else
{
Model.AddRelationship(relationship);
}
Part of me thinks it should be on the developer to validate the call before calling it. After all, adding the relationship isn't what would crash the program, it's when some other code performs an operation that results in an infinite loop. On the other hand, I feel obligated to keep the Model in a safe state at all times, and that I need to force developers to handle the bad circular reference situation by doing something like this:
// In the model itself:
public function AddRelationship(relationship:Relationship):Boolean
{
var success:Boolean = true;
if(this.AddingRelationshipWillCreateACircularReference(relationship))
{
success = false;
}
else
开发者_开发问答 {
this.addRelationship(relationship);
}
return success;
}
That way they either know that it isn't possible to add, or the relationship simply doesn't get added. That also feels wrong. Can anyone give me some thoughts that might help give me some clarity? Thanks in advance.
By convention, "Errors" indicate situations that the application just cannot handle or recover from it cleanly (ie, Disk Crash). Exception are abnormal situations that the application may try to recover from, or even clean up itself before shutting down.
I have find useful to split Exceptions in two more types: Business Exceptions, which are conditions caused by misconfiguration or mishandling of the application (ie, Validation exceptions), and Technical Exception which are conditions not caused by the application itself (ie, lost connection to the Database, Socket timeout, etc).
Back to your question, pat of you is right: the model should be keep consistent at all times, and that should be enforced at the lowest level possible to promote reuse. Thus, put the validation in the model, try the operation and if it fails inform the user. If you don't have Exceptions as a native mechanism in your language, I would go as far as returning a "result code" indicating the resulting status of the operation (ie, 0 - Success, 1 - Circular Dependency, 2 - Some unknown reason, etc).
I usually use the rule that if the user can correct the "error", then don't throw an exception. If the "error" is something truly unexpected and the user cannot fix his or her input to get past it, then it should throw an Exception.
To go a level deeper, if you are actively checking for problems, such as writing code to make sure a file or folder path exists, then you should gracefully handle the situation and present it to the user without throwing an Exception.
精彩评论