Disposer does not cleanup after rejection
See original GitHub issueGood day everyone,
today I encountered an issue with the Disposer object which looked pretty nice at first glance but seems to be a tricky to use.
First things first:
- Bluebird version: 3.5.0
- Platform: Windows 7 (x64)
- Node version: 4.4.3
“Did this issue happen with earlier versions of bluebird”? I am not sure. First I thought it worked with 3.3.5 but that was not the case.
The issue
Alright, I might not use the correct approach to use Disposers and Promise.using
so please let me know when I failed that regard - if I didn’t mess up it might be my understanding of Disposers and resources in general; Again, please let me know.
Code explains better than my linguistic skills would allow:
'use strict';
const Promise = require('bluebird');
function eww() {
return Promise.reject(new Error('evil issue'))
.delay(100)
.disposer(() => {
console.log('should be called but never is');
});
}
Promise.using(eww(), () => {
console.log('positive case - never called');
})
.catch((err) => {
console.log('failed as expected - resource is not cleaned up.');
})
The basic issue is that my disposer function is never called which should be a Bluebird issue. The reason being - again, my understanding - that whenever I attempt to claim a resource, the disposer always takes care about the proper cleanup.
Currently, when my resource claiming function (eww()
from the example) fails, I have to manually clean up my mess - which may is impossible when I wrap my code behind the disposer.
The problem is this code chunk.
The issue is not to be mistaken with this issue. I suspect it never worked like I thought it would…
Can anyone confirm this behavior? I wonder if this is intended. If I have to manually clean up after disposers, I rather not use them at all. The caller should not care about cleaning up in such cases - especially in rejection cases.
Edit:
I changed the code within the using.js to the following (resource
method):
Disposer.prototype.resource = function () {
if (this.promise().isFulfilled()) {
return this.promise().value();
}
if (this.promise().isRejected()) {
return this.promise().reason();
}
return NULL;
};
This causes the disposer to work as intended. If this is a proper change to you, let me know and I’ll PR you it.
Best regards, Philipp
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (1 by maintainers)
Disposer cannot be called because there is nothing to call it with.
@benjamingr Ahh, I just read your comment there. I didn’t know that a
.disposer
function requires to guarantee no throw.Thanks for the link!