mirror of
https://github.com/bower/bower.git
synced 2026-02-12 06:55:04 -05:00
Add a fail fast mechanism instead of rejecting the whole process on error.
This prevent clobbering registry and cache, since when the promise is rejected usually process.exit(1) is called.
This commit is contained in:
@@ -64,6 +64,7 @@ Manager.prototype.resolve = function () {
|
||||
this._fetching = {};
|
||||
this._nrFetching = 0;
|
||||
this._failed = {};
|
||||
this._failFast = false;
|
||||
this._deferred = Q.defer();
|
||||
|
||||
// If there's nothing to resolve, simply dissect
|
||||
@@ -195,6 +196,11 @@ Manager.prototype._fetch = function (decEndpoint) {
|
||||
var deferred = this._deferred;
|
||||
var that = this;
|
||||
|
||||
// Check if the whole process is marked to fail fast
|
||||
if (this._failFast) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark as being fetched
|
||||
this._fetching[name] = this._fetching[name] || [];
|
||||
this._fetching[name].push(decEndpoint);
|
||||
@@ -204,15 +210,13 @@ Manager.prototype._fetch = function (decEndpoint) {
|
||||
// Note that the promise is stored in the decomposed endpoint
|
||||
// because it might be reused if a similar endpoint needs to be resolved
|
||||
decEndpoint.promise = this._repository.fetch(decEndpoint)
|
||||
// When done, call onFetch
|
||||
.spread(this._onFetch.bind(this, deferred, decEndpoint))
|
||||
// If it fails, we make the whole process to error out
|
||||
.fail(function (err) {
|
||||
that._extendNotification(err, decEndpoint);
|
||||
deferred.reject(err);
|
||||
})
|
||||
// When done, call onFetchSuccess
|
||||
.spread(this._onFetchSuccess.bind(this, deferred, decEndpoint))
|
||||
// If it fails, call onFetchFailure
|
||||
.fail(this._onFetchError.bind(this, deferred, decEndpoint))
|
||||
// Listen to progress to proxy them to the resolve deferred
|
||||
// Note that we also mark where the notification is coming from
|
||||
// Note that we also add additional information to it, such as
|
||||
// where the notification is coming from
|
||||
.progress(function (notification) {
|
||||
that._extendNotification(notification, decEndpoint);
|
||||
deferred.notify(notification);
|
||||
@@ -221,18 +225,38 @@ Manager.prototype._fetch = function (decEndpoint) {
|
||||
return decEndpoint.promise;
|
||||
};
|
||||
|
||||
Manager.prototype._onFetch = function (deferred, decEndpoint, canonicalPkg, pkgMeta) {
|
||||
Manager.prototype._onFetchError = function (deferred, decEndpoint, err) {
|
||||
var name = decEndpoint.name;
|
||||
|
||||
this._extendNotification(err, decEndpoint);
|
||||
|
||||
// Remove from being fetched list
|
||||
mout.array.remove(this._fetching[name], decEndpoint);
|
||||
this._nrFetching--;
|
||||
|
||||
|
||||
// Add to the failed list
|
||||
this._failed[name] = this._failed[name] || [];
|
||||
this._failed[name].push(err);
|
||||
delete decEndpoint.promise;
|
||||
|
||||
// Make the whole process to fail fast
|
||||
this._failFast = true;
|
||||
|
||||
// If the resolve process ended, parse the resolved packages
|
||||
// to find the most suitable version for each package
|
||||
if (this._nrFetching <= 0) {
|
||||
process.nextTick(this._dissect.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Manager.prototype._onFetchSuccess = function (deferred, decEndpoint, canonicalPkg, pkgMeta) {
|
||||
var name;
|
||||
var resolved;
|
||||
var index;
|
||||
var initialName = decEndpoint.name;
|
||||
|
||||
// If the deferred associated with the process is already rejected,
|
||||
// do not proceed.
|
||||
if (deferred.promise.isRejected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove from being fetched list
|
||||
mout.array.remove(this._fetching[initialName], decEndpoint);
|
||||
this._nrFetching--;
|
||||
@@ -320,8 +344,18 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) {
|
||||
};
|
||||
|
||||
Manager.prototype._dissect = function () {
|
||||
var suitables = {};
|
||||
var err;
|
||||
var suitables;
|
||||
|
||||
// If something failed, reject the whole resolve promise
|
||||
// with the first error
|
||||
if (this._failFast) {
|
||||
err = mout.object.values(this._failed)[0][0];
|
||||
this._deferred.reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
suitables = {};
|
||||
mout.object.forOwn(this._resolved, function (decEndpoints, name) {
|
||||
var nonSemver;
|
||||
var validSemver;
|
||||
|
||||
Reference in New Issue
Block a user