Returning validation result from method: exception, status code...?

S

Sean Tynan

I want to find out the best way for a method to notify calling code of
situations such as validation errors, etc. that may occur during method
execution.

e.g. say I have a method (business logic layer) that inserts a user into a
database, and returns the newly created UserID:

public function CreateUser(userName as string, userEmail as string)
dim userID as integer

'Insert user details into Users table in database
'Set userID

return userID
end function

Two possible conditions must be handled:

1. The user name already exists in the database
2. The user email already exists in the database

What is the recommended way of reporting these conditions to the calling
code?

Maybe:

1. Create custom Exceptions such as NameClashException, EmailClashException.
The CreateUser function will throw the appropriate exception if any of
these situations occur.
The calling code (presentation layer) can then catch these exceptions
and notify the user as appropriate

2. Return Status enum.
The calling code can then examine the status enum and notify the user as
appropriate.
However, another way must be found for returning the userID, e.g. pass
ByRef:

public enum CreateUserStatus
Success
NameClash
EmailClash
end enum

public function CreateUser(byRef UserID as integer, userName as string,
userEmail as string)
dim userID as integer
dim status as CreateUserStatus

'Insert user details into Users table in database
'Set status and userID

return status
end function

I have read in MS docs that option 1 is not recommended as exceptions should
only be thrown if the assumptions of the method are breached.
A clashing name or email is therefore not really an exception. Also, new
exception classes would need to be created for every possible status apart
from success.

Option 2 seems messy since it makes sense for a CreateUser method to return
just the newly created user ID.

I want to find the optimal solution for this scenario and standardise my
method calls across the application to this solution.

Any ideas?


Hope this is clear.

- Sean.
 
J

Jay B. Harlow [MVP - Outlook]

Sean,
Duplicate keys in the database sounds like Exceptions to me.

I would avoid your #2 as it is far too easy to ignore the return values.

I would consider combining both methods, and have a ClashException that
accepted either a status or a field name of what clashed, I would possible
either use or inherit from ArgumentException for this.

Throw New ArgumentException("The user name already exists in the database,
"userName")
Throw New ArgumentException("The user email already exists in the database,
"userEmail")

or

Throw New ClashException(ClashStatus.Email)
Throw New ClashException(ClashStatus.Name)

Also I would verify there was not a clash before I called the CreateUser
function, for example, when the user typed in the User name, I would
validate that the user name was distinct. When the user typed in the Email
name I would verify that the email name was distinct.

Hope this helps
Jay
 
S

Sean Tynan

Thanks Jay.

I think what you outlined is the most concise way of doing it.

Do you think other situations like invalid logons, missing data, data that
exceed maximum length, etc.

also fit into this approach?

Throw New AccountExpiredException()

Throw New MissingDataException("Phone")

Throw New MaximumLengthExceededException("Address")

I guess it all depends on whether these situations are considered
exceptions. Of course there is a danger here of using the CLR's exception
handling as a kind of communication process for transmitting data other than
return values between method calls. Still, the simplicity of this approach
is appealing.

Thanks again.

- Sean
 
J

Jay B. Harlow [MVP - Outlook]

Sean,
Unfortunately there is no easy answer.

Missing Data and Maximum Length Exceeded sounds like Validation to me, I
would use exceptions for Validation per se. I would use the Validating event
for Validation.

However it can be advisable to "validate" your parameters when you call a
method of an Object, especially if you do not know who is calling the
object, in this case I would raise exceptions...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top