Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hook for ko.onBindingError #1628

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

brianmhunt
Copy link
Member

This PR should exposes a function (ko.onBindingError) to hook into binding errors.

This should give greater control to users handling cases such as #1626

The function onBindingError(spec) takes one object, spec containing the following properties:

Property Meaning
during (string) The binding function name (init or update or apply)
errorCaptured (Error) The error that was thrown by the binding function
element (HTML Node) The node the binding was being applied to
bindingKey (string) The name of the binding (init or update only)
valueAccessor (function) As passed to the binding function (init or update only)
allBindings (function) As passed to the binding function (init or update only)
bindingContext (object) As passed to the binding function (contains $data, $rawData, $root, ...)

Tested on PhantomJS, Chrome, Safari, and Firefox.

@xavierzwirtz
Copy link

I like it, makes the error handlers you referenced in #1626 much easier to write.
+1

@brianmhunt
Copy link
Member Author

Thanks @voiceofwisdom ... My thinking too is that there are lots of folks using error reporters like (from https://plus.google.com/+PaulIrish/posts/12BVL5exFJn):

  • github.com/Offbeatmammal/jsErrLog
  • github.com/occ/TraceKit
  • bugsense.com
  • jslogger.com
  • qbaka.com
  • muscula.com
  • errorception.com
  • exceptionhub.com
  • bugsnag.com
  • exceptional.io
  • airbrake.io
  • getsentry.com

Plus any number of variants the in-house. Writing a custom binding provider is a somewhat ominous barrier to work with these services, especially if you're new to Knockout.

I glean from their number that there is some popularity to them.

@brianmhunt
Copy link
Member Author

@mbest, @rniemeyer @SteveSanderson — any thoughts on this PR?

@rniemeyer
Copy link
Member

I think this is good functionality. A custom binding provider is harder to jump into than a hook like this one.

@brianmhunt
Copy link
Member Author

A couple extra features:

  • Errors on subsequent calls to the update function will now be captured and passed to ko.onBindingError
  • Multiple applyBindings will call ko.onBindingError
  • The default onBindingError error message will now print "Unable to process binding \"" + spec.bindingKey + "\" in binding \"" + bindingText + "\"\nMessage: " + error.message, where bindingText is the entire binding string (e.g. the data-bind attribute)

Tested on Chrome, Safari, Firefox, and PhantomJS.


try {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this "outer" try necessary if we have the "inner" try below inside the ko.dependentObservable?

@brianmhunt
Copy link
Member Author

Thank you @rniemeyer !

@mbest, @SteveSanderson - I am tagging this for 3.3 - even though I expect it would not make it in. This PR seems a fairly straightforward patch, would be handy for lots of folks, and it would be good to get it into the "stream" for release (expecting it'll be 3.4 or later, but great if it were good enough for 3.3).

The one concern I have is that errors will now be thrown when handlerUpdateFn is called, not just when it is bound/initialized. i.e. this differs from the current handling.

I would be very grateful for thoughts on how “mergeable” this looks.

Cheers

@brianmhunt brianmhunt added this to the 3.3.0 milestone Jan 6, 2015
@brianmhunt brianmhunt mentioned this pull request Jan 6, 2015
3 tasks
@brianmhunt brianmhunt modified the milestones: 3.3.0, 3.4.0 Jan 8, 2015
@SteveSanderson
Copy link
Contributor

@brianmhunt, could you let us know what (if anything) you think we should still do here, in light of #1715 having been merged now?

@brianmhunt
Copy link
Member Author

@SteveSanderson – I've been mulling it.

I am guessing the easiest way to preserve the functionality would be to directly attach the metadata to the error instances. We just have to be wary of clobbering anything currently or possibly in the future native to the Error, but the spec for Errors is pretty bare.

We could just change the onBindingError spec and respective calls so the spec looks like this:

    ko.onBindingError = function(error, spec) {
        var bindingText;
        ko.utils.extend(error, spec);
        if (spec.bindingKey) {
            // During: 'init' or initial 'update'
            bindingText = ko.bindingProvider['instance']['getBindingsString'](spec.element);
            error.message = "Unable to process binding \"" + spec.bindingKey + 
                 "\" in binding \"" + bindingText + "\"\nMessage: " + error.message;
        } // else: During: 'apply'

        if (ko['onError']) {
          ko['onError'](error);
        } else {
          throw error;
        }
   }

Does that sound – roughly – like a reasonable tact?

Incidentally, I noted that ko.utils.catchFunctionErrors rethrows an error even if ko.onError exists. Might it be preferable to leave it up to the user whether they want the error to rethrow? They can easily add it to their ko.onError handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants