I'm aware that clean And maintainable code is more important than premature optimizations. Throwing exceptions seems to be more suggestive than return codes. But i'm not talking about return codes. Here a example.
function SignIn(user) {
const userExist = logics()
if (!userExist) throw UserNotExistError('message', user)
const token = generateToken(user)
return token
}
Here's the same but with return objects
function SignIn(user) {
const userExist = logics()
if (!userExist) return {token: null, error: 'no-user'}
const token = generateToken(user)
return {token, error: null}
}
The second looks like a better option to me. Because handling exceptions is theoretically less performant, and with try/catch is it's sync. Besides over time there'll be lots of exceptions.
UserNotExistError, UserExistError, ValidationError, DBError, QueryFailedError, UnknownError, FunctionSpecificError, OtherFunctionSpecificError.
And I myself noticed few millisecs delay in requests when handling exceptions on my computer and on a relatively small project. It can add up in a larger scale.
I'm by no means not saying not to use exceptions. They're quite handy. But why everywhere, when a signup/signin fails, something doesn't exist or does..
The lots of SO threads seem to discuss more about theory and less specific details. What about your opinion? How have you been doing this?
Top comments (2)
Since you tagged your post with #functional: I think you've made the right conclusion by favoring a return value over an effect (of throwing) but for the wrong reason. The functional paradigm paves the way for math in programming. Functions don't have effects in math. As soon as you treat effects as values and defer their execution, you greatly simplify your code, because now you can reason locally and equationally about it.
You might really like Lua then :D