Returning type-safe & non-nil failure in Crystal?

mjb2kmn

MN Mark

Posted on February 18, 2019

Returning type-safe & non-nil failure in Crystal?

I am having design doubts in Crystal and would like to hear how others have implemented similar functionality.

The User class has a method to fetch data based on some attribute value and return an instance.

class User
  def self.get_by_login(login : String)
    obj = DB.irrelevant_method(login)
    return obj
  end
end

(I am using superfluous return statements to be more illustrative of intent)

The issue comes in when the database does not find a record to return. I do not want to return a union type such as (User|Nil) or (User|Bool). My idea is to return a User instance to satisfy the return type with the specific error added to an existing errors array I'm already using for validation on the creation side.

class User
  def self.get_by_login(login : String)
    user = User.new
    begin
      user = DB.irrelevant_method(login)
    rescue ex
      user.errors << ex.to_s
    end
    return user
  end
end

This leaves it up to the caller to check if the returned object is valid or has any errors before knowing what to do with it.

Any thoughts or concerns about this approach in Crystal or in general? I've used this pattern before in other languages and it does work, but I've never really felt great about it. I'm curious to hear how others have solved this or similar issues in Crystal or other strongly typed languages.

💖 💪 🙅 🚩
mjb2kmn
MN Mark

Posted on February 18, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related