Reputation: 1621
If face a logic error error such (Expired user, invalid ID)
, then what is the best way to tell the parent method of this error from the following :
1- Throwing customized exception like the following :
try
{
//if (ID doesn't match) then
Throw new CustomException(-1,"ID doesn't match");
}
catch(CustomException ex)
{
throw ex
}
catch(Exception ex)
{
throw new CustomException(ex.ErrorCode,ex.message);
}
2- return error message and code like :
//if (ID doesn't match) then
This.ErrorCode= -1;
This.Message= "ID doesn't match";
Upvotes: 9
Views: 29801
Reputation: 7894
The better way is to throw custom exception. That's why they were introduced. If you need to provide specific info, like ErrorCode
or something else, you could easily extend base Exception
class to do so. Main reasons are:
Exception
is something you can't ignore. Upvotes: 5
Reputation: 1265
If face a logic error error such (Expired user, invalid ID), then what is the best way to tell the parent method of this error
Since you want the parent method to know the error, it seams that you are not sure that ID
is valid and the User
is not expired before you call the GetUser
method. Right?
If you are not sure that parameters you pass into the function are valid, then using exceptions is not justified and you should return error information instead.
You can return error information more functional way similar to what Scala, Go and Rust languages suggest.
Create a generic class to return either an error or a value
public class Either(of ErrorType, ValueType)
public readonly Success as boolean
public readonly Error as ErrorType
public readonly Value as ValueType
public sub new(Error as ErrorType)
me.Success = False
me.Error = Error
end sub
public sub new(Value as ValueType)
me.Success = True
me.Value = Value
end sub
end class
Create an enumeration of errors that your function can have
public enum UserError
InvalidUserID
UserExpired
end enum
Create a function that takes a User ID as an argument and returns either an error or a User
function GetUser(ID as integer) as Either(of UserError, User)
if <business logic to find a user failed> then
return new Either(of UserError, User)(UserError.InvalidUserID)
end if
if <user expired> then
return new Either(of UserError, User)(UserError.UserExpired)
end if
return new Either(of UserError, User)(User)
end function
In the caller (parent) method check for the error and apply business logic
dim UserID = 10
dim UserResult = GetUser(10)
if UserResult.Success then
rem apply business logic to UserResult.Value
else
rem apply business logic to UserResult.Error
end if
Note: if you rewrite this code using Exceptions you will get exactly the same amount of code.
Upvotes: 4
Reputation: 7919
It entirely depends of the workflow of your project. If it is an unexpected run timer error and it inhibits your program then exception is a good choice but for simple input checks and expectable outputs you should use enumerators
Upvotes: 0
Reputation: 8937
I suppose you should use exceptions, because it is exact, what they are made for. You can put there the same information, as in you second case. But the difference between 1-st and 2-nd one is that you give your function consumers a possibility to be informed that something wrong, and it MUST be handled somehow. In second case you just say that function worked, but something wrong, and user MAY handle this information
Upvotes: 2
Reputation: 6698
In most cases you should throw an exception. Whether this is a standard or custom exception depends on the context, but is irrelevant to the process.
Throwing exceptions forces any implementation to handle bad data accordingly. If you rely on implementations to check property values for correct processing, then unexpected, harder to debug exceptions will be encountered sooner or later.
Upvotes: 2