Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Add CompositeDisposable::addIfDisposable #12

Closed
wants to merge 7 commits into from
Closed

Conversation

as-cii
Copy link
Contributor

@as-cii as-cii commented Jul 7, 2015

This should allow package developers to catch issues like atom/tabs#183 early on.

This method will allow to have less strict checks whenever we add a disposable for code that we do not manage, thereby avoiding issues like atom/tabs#183 altogether.

/cc: @kevinsawicki @benogle

@@ -29,3 +29,10 @@ describe "CompositeDisposable", ->
expect(disposable1.disposed).toBe true
expect(disposable2.disposed).toBe false
expect(disposable3.disposed).toBe true

it "denies to add an object that does not respond to ::dispose", ->
Copy link
Contributor

Choose a reason for hiding this comment

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

🎨 What about rejects an object that does not implement ::dispose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It’s probably better but eventually I went with throws an error, as it’s more consistent with how specs are named in atom/atom. Thanks! 🙇

@kevinsawicki
Copy link
Contributor

Since disposable.dispose could be altered after it is added to the disposables array, I think this case should be explicitly guarded against during CompositeDisposable::dispose as well.

@kevinsawicki
Copy link
Contributor

Also, do you know if this would cause the git-log package to now be associated with the error notification instead of the tabs package for the referenced issue case?

@as-cii
Copy link
Contributor Author

as-cii commented Jul 7, 2015

Since disposable.dispose could be altered after it is added to the disposables array, I think this case should be explicitly guarded against during CompositeDisposable::dispose as well.

Nice catch, I have just added it. 👍

Also, do you know if this would cause the git-log package to now be associated with the error notification instead of the tabs package for the referenced issue case?

I think the error will still be raised on tabs in that particular case but in a different moment and with a more insightful error message. The matter with that package is that some functions are implemented without respecting “the contract” between TabView and its @item.

Ideally, a type system would warn us about such kinds of issues but given that there isn't one, I think this is best thing we could possibly do. Also, I wouldn’t silently skip null disposables, as I see it as a potential root of problems.

@kevinsawicki: thoughts?

@kevinsawicki
Copy link
Contributor

@kevinsawicki: thoughts?

Yeah, thinking about the tabs example, it would seem unfortunate to have to wrap calls to add and dispose now in a try/catch since showing a notification isn't helpful at all and associating the pane item to a package is difficult/impossible.

Having CompositeDisposable throw exceptions makes feature degradation based on expected APIs not returning disposables rather challenging to work around.

I feel like the pattern will be people just wrapping these methods in try/catch blocks that do nothing and just moving on.

@as-cii as-cii changed the title Allow only objects implementing ::dispose in CompositeDisposable Add CompositeDisposable::addIfDisposable Jul 8, 2015
@as-cii
Copy link
Contributor Author

as-cii commented Jul 8, 2015

The problem this PR is trying to address comes from a package not respecting an API’s implementation contract. In particular, atom/tabs#183 was caused by the package implementing a function (which was supposed to return a Disposable) by returning null instead.

Ideally, a type system would catch these kinds of errors early on thereby solving the problem altogether. However, since we haven’t got such facility in our environment, how can we solve it?

This PR was initially created to put stricter guards whenever we added new disposables to a CompositeDisposable. At first, I was convinced that we needed to raise an error as early as possible, so that package authors could have better insights on what to do when things failed.

After discussing about this with @kevinsawicki, though, we agreed that there could have been situations where package authors simply ignored these new exceptions, thus leaving the problem unsolved. Therefore we decided to introduce a new API (addIfDisposable) that simply ignores objects that do not respect the Disposable contract; this should be used when dealing with code that we do not manage, such as the one that caused the exception in the aforementioned issue. add, on the other hand, should be kept for scenarios where we want stricter checks, such as core code.

@benogle @maxbrunsfeld @nathansobo: what do you think?

@nathansobo
Copy link
Contributor

I feel a bit weirded out about expanding the API of what is otherwise a super minimal library. How many places do we anticipate using this method? Would it be rare enough to just guard the value in those cases and go ahead and throw exceptions from the core library?

@maxbrunsfeld
Copy link
Contributor

I still think CompositeDisposable::add should throw an exception if the argument doesn't implement .dispose(). In most cases, something's wrong if we're trying to do that, and It'll often be a memory leak. I don't think we'd ever want to purposefully catch that exception, since it's a programmer mistake, not a runtime error condition.

I think that if we went that route, we should have TabView check the return value of ::onDidChangeTitle and friends, and log a warning to the console if they don't return disposables. Maybe we should add a Disposable.isDisposable() to clarify what we're doing when we check.

@nathansobo
Copy link
Contributor

Maybe we should add a Disposable.isDisposable() to clarify what we're doing when we check.

👍

@as-cii
Copy link
Contributor Author

as-cii commented Aug 24, 2015

Closing in favor of #15. Thanks everyone for your feedback! 🙇

@as-cii as-cii closed this Aug 24, 2015
@as-cii as-cii deleted the as-guard-disposable branch August 24, 2015 07:55
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants