Permalink
Browse files

packager: Module: get rid of callbacks

Summary: By getting rid of callbacks, we get a code that's pretty halved in size, and much easier to read, but we also fix bugs! When some of the code of Module would throw, we wouldn't catch it, meaning that packager would crash entirely. That's the case for when we have a Haste name mistach, for example. This changeste fixes that by instead capturing exceptions through the Promise chain, that bubble up all the way to the `Server` and reasonnably handled. People can then fix the Haste nane mismatch and refresh right away, and it'll work as expected.

Reviewed By: davidaurelio

Differential Revision: D5137408

fbshipit-source-id: b9e938b93e8d23738af49106bbae1fce97d7a5db
  • Loading branch information...
jeanlauliac authored and facebook-github-bot committed May 26, 2017
1 parent e9fc731 commit 21e3d4db204de98446272fdfbd30eeb1b3966771
Showing with 32 additions and 79 deletions.
  1. +32 −79 packager/src/node-haste/Module.js
@@ -265,80 +265,44 @@ class Module {
return {...result, id: this._getHasteName(), source};
}
_transformCodeForCallback(
async _transformCodeFor(
cacheProps: ReadTransformProps,
callback: (error: ?Error, result: ?TransformedCode) => void,
) {
): Promise<TransformedCode> {
const {_transformCode} = this;
invariant(_transformCode != null, 'missing code transform funtion');
const {sourceCode, transformOptions} = cacheProps;
return _transformCode(this, sourceCode, transformOptions).then(
freshResult => process.nextTick(callback, undefined, freshResult),
error => process.nextTick(callback, error),
);
return await _transformCode(this, sourceCode, transformOptions);
}
_transformAndStoreCodeGlobally(
async _transformAndStoreCodeGlobally(
cacheProps: ReadTransformProps,
globalCache: GlobalTransformCache,
callback: (error: ?Error, result: ?TransformedCode) => void,
) {
this._transformCodeForCallback(
cacheProps,
(transformError, transformResult) => {
if (transformError != null) {
callback(transformError);
return;
}
invariant(
transformResult != null,
'Inconsistent state: there is no error, but no results either.',
);
globalCache.store(cacheProps, transformResult);
callback(undefined, transformResult);
},
);
): Promise<TransformedCode> {
const result = await this._transformCodeFor(cacheProps);
globalCache.store(cacheProps, result);
return result;
}
_getTransformedCode(
async _getTransformedCode(
cacheProps: ReadTransformProps,
callback: (error: ?Error, result: ?TransformedCode) => void,
) {
): Promise<TransformedCode> {
const {_globalCache} = this;
if (_globalCache == null || !_globalCache.shouldFetch(cacheProps)) {
this._transformCodeForCallback(cacheProps, callback);
return;
return await this._transformCodeFor(cacheProps);
}
_globalCache.fetch(cacheProps).then(
globalCachedResult =>
process.nextTick(() => {
if (globalCachedResult == null) {
this._transformAndStoreCodeGlobally(
cacheProps,
_globalCache,
callback,
);
return;
}
callback(undefined, globalCachedResult);
}),
globalCacheError => process.nextTick(() => callback(globalCacheError)),
);
const globalCachedResult = await _globalCache.fetch(cacheProps);
if (globalCachedResult != null) {
return globalCachedResult;
}
return await this._transformAndStoreCodeGlobally(cacheProps, _globalCache);
}
_getAndCacheTransformedCode(
async _getAndCacheTransformedCode(
cacheProps: ReadTransformProps,
callback: (error: ?Error, result: ?TransformedCode) => void,
) {
this._getTransformedCode(cacheProps, (error, result) => {
if (error) {
callback(error);
return;
}
invariant(result != null, 'missing result');
this._options.transformCache.writeSync({...cacheProps, result});
callback(undefined, result);
});
): Promise<TransformedCode> {
const result = await this._getTransformedCode(cacheProps);
this._options.transformCache.writeSync({...cacheProps, result});
return result;
}
/**
@@ -411,30 +375,19 @@ class Module {
if (promise != null) {
return promise;
}
const freshPromise = Promise.resolve().then(() => {
const freshPromise = (async () => {
const cacheProps = this._getCacheProps(transformOptions, key);
return new Promise((resolve, reject) => {
this._getAndCacheTransformedCode(
cacheProps,
(transformError, freshResult) => {
if (transformError) {
reject(transformError);
return;
}
invariant(freshResult != null, 'inconsistent state');
resolve(
this._finalizeReadResult(cacheProps.sourceCode, freshResult),
);
},
);
}).then(result => {
this._readResultsByOptionsKey.set(key, {
result,
outdatedDependencies: [],
});
return result;
const freshResult = await this._getAndCacheTransformedCode(cacheProps);
const finalResult = this._finalizeReadResult(
cacheProps.sourceCode,
freshResult,
);
this._readResultsByOptionsKey.set(key, {
result: finalResult,
outdatedDependencies: [],
});
});
return finalResult;
})();
this._readPromises.set(key, freshPromise);
return freshPromise;
}

0 comments on commit 21e3d4d

Please sign in to comment.