# frozen_string_literal: true # rescue from errors # # in some class # Lux::RescueFrom.define(self) -> defines rescue_from method in class # # to add # rescue_from(UnauthorizedError) { ... } # # and to resolve in the end # @@rescue_from_ivar.call { main } class Lux::RescueFrom class << self def define klass ClassAttributes.define klass, :rescue_from_hash klass.class_eval %[ @@rescue_from_ivar = Lux::RescueFrom.new def self.rescue_from(name, &block) @@rescue_from_ivar.add(name, &block) end ] end end ### def initialize @rescues = {} end def add name, &block die ":#{name} is not allowed rescue name, only allowed are :default and :allways" if name.is_symbol? && ![:default, :allways].index(name) @rescues[name.to_s] = block end # we pass context so we can execute errors it object context def call context begin yield rescue Exception => e raise e unless Lux.page return if Lux.page.body && Lux.page.status if proc = @rescues[e.class.to_s] proc.call(e.message) context.instance_exec e.message, &proc elsif proc = @rescues['default'] # catch them all context.instance_exec e.message, &proc else raise e end context.instance_exec e.message, &@rescues['allways'] if @rescues['allways'] Lux.page.status e.class end end end