Raise custom Exception with arguments

前端 未结 6 1811
礼貌的吻别
礼貌的吻别 2020-12-23 13:36

I\'m defining a custom Exception on a model in rails as kind of a wrapper Exception: (begin[code]rescue[raise custom exception]end)

When I raise the Exc

6条回答
  •  情歌与酒
    2020-12-23 14:03

    TL;DR 7 years after this question, I believe the correct answer is:

    class CustomException < StandardError
      attr_reader :extra
      def initialize(message=nil, extra: nil)
        super(message)
        @extra = extra
      end
    end
    # => nil 
    raise CustomException.new('some message', extra: "blupp")
    

    WARNING: you will get identical results with:

    raise CustomException.new(extra: 'blupp'), 'some message'
    

    but that is because Exception#exception(string) does a #rb_obj_clone on self, and then calls exc_initialize (which does NOT call CustomException#initialize. From error.c:

    static VALUE
    exc_exception(int argc, VALUE *argv, VALUE self)
    {
        VALUE exc;
    
        if (argc == 0) return self;
        if (argc == 1 && self == argv[0]) return self;
        exc = rb_obj_clone(self);
        exc_initialize(argc, argv, exc);
    
        return exc;
    }
    

    In the latter example of #raise up above, a CustomException will be raised with message set to "a message" and extra set to "blupp" (because it is a clone) but TWO CustomException objects are actually created: the first by CustomException.new, and the second by #raise calling #exception on the first instance of CustomException which creates a second cloned CustomException.

    My extended dance remix version of why is at: https://stackoverflow.com/a/56371923/5299483

提交回复
热议问题