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
    • None
    • Ruby Drivers
    • 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: