Exception handling: how granular would you go when it comes to argument validation?

試著忘記壹切 提交于 2019-12-04 19:20:53
Eric Lippert

Consider the contract that you are imposing upon the callers of SendMail. They are required to pass you a "valid email address". Who decides what is valid? SendMail does. Basically your method is "high maintenance" -- it wants things exactly the way it likes, and the only way to tell whether what you're going to give it will be satisfactory is to try and hope for the best.

Don't write high-maintenance methods without giving the caller a chance to know how to satisfy it, or at least have a way to avoid the exception. Extract the validation logic to an "IsValidAddress" method that returns a Boolean. Then have your SendMail method call IsValidAddress and throw if it is invalid.

You get several nice effects from this change:

(1) Increased separation of concerns. SendMail's job is to make the email mechanism work, not to pass judgment on whether an email address is valid. Isolate that policy decision to code that specializes in verification.

(2) Address validation is a useful tool in of itself; there are lots of times when you want to know whether an address is well-formed without sending mail to it.

(3) You can update and improve your validation logic easily because it is all in one sensible place.

(4) Callers have a way that they can guarantee that no exception will be thrown. If a caller cannot call a method without guaranteeing that the arguments are valid, then they have to catch the exception. Ideally you should never make a caller have to handle an exception to make their code correct; there should be a way they can write correct code that never throws, even if the data they've been handed is bad.

Here are a couple of articles I've written on this subject that you might find helpful:

Exception handling: http://ericlippert.com/2008/09/10/vexing-exceptions/

High-maintenance methods: http://blogs.msdn.com/ericlippert/archive/2008/09/08/high-maintenance.aspx

Having two throw statements in a row makes no sence - only the first one will be executed and then control will be passed to the exception handler and never to the second throw.

In my opinion it is more than enough to just say smth like "Sender e-mail is invalid." An e-mail is quite simple and short and so the user will be able to resolve this without any additional guidance.

I also think it would be better to first check all the passed in values and only then start work. What's the point in partially doing work if you can then encounter an invalid parameter value and throw an exception and never complete this work. Try to indicate errors as early as you can - at the very beginning if possible.

And:

Use

string.IsNullOrEmpty(subject)

rather than

subject == null

for checking if your strings are empty.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!