Forem

Kat Padilla
Kat Padilla

Posted on • Originally published at blog.katpadi.ph on

3 1

Handling Errors Gracefully

Sometimes it makes sense to treat errors as part of an application's "valid" flow of events. Meaning, expected errors should not necessarily make your code go crazy when random errors are raised.

With that in mind, I created a way to implement some kind of "Result Object" by rescuing StandardError instances and handling these errors gracefully.

class Gracefully
  class << self
    alias_method :handle, :new
  end

  attr_reader :error, :value

  def initialize
    @value = nil
    @error = nil
    begin
      @value = yield
    rescue => e
      @error = e
    end
  end

  def success?
    error.nil?
  end

  def on_success
    return self unless success?
    result = yield(@value)
    return result if result.is_a?(Gracefully)
    Gracefully.handle { result }
  end

  def on_failure
    return self if success?
    result = yield(@error)
    return result if result.is_a?(Gracefully)
    Gracefully.handle { result }
  end
end

gracefully.rb view raw

In short, _ Gracefully _ is a wrapper for a result object– it’s either a success value or an error object.

result = Gracefully.handle { Order.find 999 }

In the example above, if order with id 999 does not exist, result.success? method will return false. Otherwise, true.

If result.success?is true, result.value will contain the successful value. Otherwise, result.error will hold the error object itself.

Whenever Gracefully.handle is called, it will return a Gracefully object. If you want to get the raw value, you can use result.value.

More Usage

result = Gracefully.handle { ComplicatedService.new(foo, bar).process }
if result.success?
  # do success stuff
  use_value(result.value)
else
  # do failure stuff
  log_error(result.error)
end

Chaining Usage

Gracefully.handle { SomeComplicatedService.new.call }.on_success do |val|
  val.update!(column_name: 'stuff')
end

Gracefully.handle { SomeComplicatedService.new.call }.on_failure do |e|
  do_whatever_you_wish_with_the_error(e)
end

By using this, I can be resilient in handling errors and be able to recover from failures in the process flow.

The post Handling Errors Gracefully appeared first on KatPadi's Point.

--
Visit my website @ http://katpadi.ph.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more