Mongoid::Errors::Callback is not correctly worded + has other problems

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: Callbacks
    • Ruby Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Problems with Mongoid::Errors::Callback:

      • Mongoid::Errors::Callback is not correctly worded. It says "...resulted in a false return from a callback", but as of Rails 5, returning false from an ActiveModel callback doesn't not have any effect: https://www.bigbinary.com/blog/rails-5-does-not-halt-callback-chain-when-false-is-returned
        • This wording should be changed to "...threw an :abort"
      • In addition, the error does not tell us which callback actually failed.
      • Lastly, in some cases, I think it is actually possible that this error is raised even if no callback was aborted, but if the save failed for any other reason, which is confusing. I see this happening in my app after upgrading to Mongoid 9, but I am still trying to pin down the actual problem.

      To fix/clarify things, I'd like would propose the following enhancement:

      1. Make a new error class "Mongoid::Errors::CallbackAborted". This should be raised during the actual abort, and make it clear in the error exactly which callback was aborted.
      2. If no callback aborted, instead, raise a new generic error class "Mongoid::Errors::PersistenceFailed"
      3. To preserve the legacy error, make:
        1. Mongoid::Errors::Callback = Mongoid::Errors::PersistenceFailed
        2. Mongoid::Errors::CallbackAborted < Mongoid::Errors::PersistenceFailed (CallbackAborted is a subclass)

      Demonstration that returning false in a callback has no effect in MongoDB:

      class Person
        include Mongoid::Document
      
        before_save :return_false
      
        def return_false
          throw(:abort)
        end
      end
      
      Person.new.save! #=> true, it works!

      Instead, this error is raised if you throw(:abort)

       

      class Person
      include Mongoid::Document 
        before_save :throw_abort
      
        def throw_abort
          throw(:abort)
        end
      end
      
      Person.new.save! #=> raises error blelow

       

      Mongoid::Errors::Callback: 
      message:
        Calling save! on Person resulted in a false return from a callback.
      summary:
        If a before callback returns false when using Document.create!, Document#save!, or Document#update_attributes! this error will get raised since the document did not actually get saved.
      resolution:
        Double check all before callbacks to make sure they are not unintentionally returning false.

            Assignee:
            Unassigned
            Reporter:
            Johnny Shields
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: