Context of an Error

T

Trans

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

x = SomeClass

def dosomething
x.bar
end

begin
dosomething
rescue NoMethodError
p e.context #=> SomeClass (HOW?)
end

Thanks,
T.
 
A

ara.t.howard

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

x = SomeClass

def dosomething
x.bar
end

begin
dosomething
rescue NoMethodError
p e.context #=> SomeClass (HOW?)
end

Thanks,
T.

but, imho, that's not the context. the context would be 'dosomething' ? can
you explain what you mean by 'context'? if by context you mean the object
raising the NoMethodError, you can do obviously hook into method_missing to
make it add this info to every execption, otherwise this is all you've got:

harp:~ > cat a.rb
class C; end

begin
C.foobar
rescue NoMethodError => ne
(NoMethodError.instance_methods - Object.instance_methods).sort.each do |m|
p m => ne.send(m)
end
end

harp:~ > ruby a.rb
{"args"=>[]}
{"backtrace"=>["a.rb:4"]}
{"exception"=>#<NoMethodError: undefined method `foobar' for C:Class>}
{"message"=>"undefined method `foobar' for C:Class"}
{"name"=>:foobar}
a.rb:7:in `set_backtrace': wrong number of arguments (0 for 1) (ArgumentError)
from a.rb:7
from a.rb:6

so, other than scraping that info - which does contain what you want - i think
adding an attr to Exception and making method_missing set it on the way out
might be the only way to go...

cheers.

-a
 
L

Logan Capaldo

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

x = SomeClass

def dosomething
x.bar
end

begin
dosomething
rescue NoMethodError
p e.context #=> SomeClass (HOW?)
end

Thanks,
T.
I don't know if there is a builtin way but:
class Object
alias lmc_ruby_raise raise
def raise(*args)
if args.length >= 2
# class + some args
klass, *rem_args = args
exp = klass.new(*rem_args)
exp.instance_variable_set("@context", self.class)
lmc_ruby_raise(exp)
elsif args.length == 1
case args[0]
when Class
exp = args[0].new
exp.instance_variable_set("@context", self.class)
lmc_ruby_raise( exp )
when String
exp = RuntimeError.new(args[0])
exp.instance_variable_set("@context", self.class)
lmc_ruby_raise( exp )
else
exp = args[0]
exp.instance_variable_set("@context", self.class)
lmc_ruby_raise( exp )
end
end
end
end

class Exception
attr_reader :context
end

Totally untested of course.
 
L

Logan Capaldo

Perhaps this should be
module Kernel

since that's where raise actually lives.
Well actually if I put it in Object and raise is defined in Kernel that
would simplify my code. No need for an alias, just use super
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,214
Messages
2,571,112
Members
47,705
Latest member
noname22

Latest Threads

Top