C. Scott Ananian has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/402436 )

Change subject: Use Promise.async/yield for lib/api/routes.js
......................................................................

Use Promise.async/yield for lib/api/routes.js

Change-Id: If181edf096861e31dc8d5fa20910fb8ab8a511d4
---
M lib/api/apiUtils.js
M lib/api/routes.js
2 files changed, 140 insertions(+), 135 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid 
refs/changes/36/402436/1

diff --git a/lib/api/apiUtils.js b/lib/api/apiUtils.js
index 7bf3c76..4071c0b 100644
--- a/lib/api/apiUtils.js
+++ b/lib/api/apiUtils.js
@@ -166,6 +166,12 @@
        env.log('fatal/request', err);
 };
 
+apiUtils.errorWrapper = function(env, promiseOrValue) {
+       return Promise.resolve(promiseOrValue).catch(function(err) {
+               apiUtils.errorHandler(env, err);
+       });
+};
+
 // To support the 'subst' API parameter, we need to prefix each
 // top-level template with 'subst'. To make sure we do this for the
 // correct templates, tokenize the starting wikitext and use that to
diff --git a/lib/api/routes.js b/lib/api/routes.js
index 089dbe5..4a30106 100644
--- a/lib/api/routes.js
+++ b/lib/api/routes.js
@@ -254,7 +254,7 @@
 
        // Spec'd in https://phabricator.wikimedia.org/T75955 and the API tests.
 
-       var wt2html = Promise.method(function(req, res, wt, reuseExpansions) {
+       var wt2html = Promise.async(function *(req, res, wt, reuseExpansions) {
                var env = res.locals.env;
                var opts = res.locals.opts;
                var oldid = res.locals.oldid;
@@ -271,134 +271,132 @@
                        startTimers.set('wt2html.total', Date.now());
                }
 
-               var p = Promise.resolve(wt);
-
                if (oldid || typeof wt !== 'string') {
                        // Always fetch the page info if we have an oldid.
                        // Otherwise, if no wt was passed, we need to figure out
                        // the latest revid to which we'll redirect.
-                       p = p.tap(function() {
-                               return TemplateRequest.setPageSrcInfo(env, 
target, oldid);
-                       });
+                       yield TemplateRequest.setPageSrcInfo(env, target, 
oldid);
                }
 
+               // Calling this `wikitext` so that it's easily distinguishable.
+               // It may be modified by substTopLevelTemplates.
+               var wikitext;
                var doSubst = (typeof wt === 'string' && res.locals.subst);
                if (doSubst) {
-                       p = p.then(function(wikitext) {
-                               return apiUtils.substTopLevelTemplates(env, 
target, wikitext);
-                       });
+                       wikitext = yield apiUtils.substTopLevelTemplates(env, 
target, wt);
+               } else {
+                       wikitext = wt;
                }
 
-               return p.then(function(wikitext) {
-                       // Calling this `wikitext` so that it's easily 
distinguishable.
-                       // It may have been modified by substTopLevelTemplates.
+               // Now that we have a revid, we can redirect
+               if (typeof wikitext !== 'string' && !oldid) {
+                       return apiUtils.redirectToOldid(req, res);
+               }
 
-                       // Now that we have a revid, we can redirect
-                       if (typeof wikitext !== 'string' && !oldid) {
-                               return apiUtils.redirectToOldid(req, res);
+               // Follow redirects if asked
+               if (parsoidConfig.devAPI && req.query.follow_redirects) {
+                       // Get localized redirect matching regexp
+                       var reSrc = 
env.conf.wiki.getMagicWordMatcher('redirect').source;
+                       reSrc = '^[ \\t\\n\\r\\0\\x0b]*' +
+                               reSrc.substring(1, reSrc.length - 1) + // Strip 
^ and $
+                               '[ \\t\\n\\r\\x0c]*(?::[ \\t\\n\\r\\x0c]*)?' +
+                               '\\[\\[([^\\]]+)\\]\\]';
+                       var re = new RegExp(reSrc, 'i');
+                       var s = wikitext || env.page.src;
+                       var redirMatch = s.match(re);
+                       if (redirMatch) {
+                               return apiUtils._redirectToPage(redirMatch[2], 
req, res);
                        }
+               }
 
-                       // Follow redirects if asked
-                       if (parsoidConfig.devAPI && req.query.follow_redirects) 
{
-                               // Get localized redirect matching regexp
-                               var reSrc = 
env.conf.wiki.getMagicWordMatcher('redirect').source;
-                               reSrc = '^[ \\t\\n\\r\\0\\x0b]*' +
-                                               reSrc.substring(1, reSrc.length 
- 1) + // Strip ^ and $
-                                               '[ \\t\\n\\r\\x0c]*(?::[ 
\\t\\n\\r\\x0c]*)?' +
-                                               '\\[\\[([^\\]]+)\\]\\]';
-                               var re = new RegExp(reSrc, 'i');
-                               var s = wikitext || env.page.src;
-                               var redirMatch = s.match(re);
-                               if (redirMatch) {
-                                       return 
apiUtils._redirectToPage(redirMatch[2], req, res);
-                               }
+               var envOptions = Object.assign({
+                       pageBundle: pageBundle,
+                       // Set data-parsoid to be discarded, so that the 
subst'ed
+                       // content is considered new when it comes back.
+                       discardDataParsoid: doSubst,
+               }, res.locals.envOptions);
+
+               // VE, the only client using body_only property,
+               // doesn't want section tags when this flag is set.
+               // (T181226)
+               if (res.locals.body_only) {
+                       envOptions.wrapSections = false;
+               }
+
+               if (typeof wikitext === 'string') {
+                       // Don't cache requests when wt is set in case somebody 
uses
+                       // GET for wikitext parsing
+                       apiUtils.setHeader(res, 'Cache-Control', 
'private,no-cache,s-maxage=0');
+
+                       if (metrics) {
+                               metrics.endTiming(
+                                       'wt2html.wt.init', 
startTimers.get('wt2html.init')
+                               );
+                               startTimers.set('wt2html.wt.parse', Date.now());
+                               metrics.timing('wt2html.wt.size.input', 
wikitext.length);
                        }
+               } else if (oldid) {
+                       envOptions.pageWithOldid = true;
 
-                       var envOptions = Object.assign({
-                               pageBundle: pageBundle,
-                               // Set data-parsoid to be discarded, so that 
the subst'ed
-                               // content is considered new when it comes back.
-                               discardDataParsoid: doSubst,
-                       }, res.locals.envOptions);
-
-                       // VE, the only client using body_only property,
-                       // doesn't want section tags when this flag is set.
-                       // (T181226)
-                       if (res.locals.body_only) {
-                               envOptions.wrapSections = false;
-                       }
-
-                       if (typeof wikitext === 'string') {
-                               // Don't cache requests when wt is set in case 
somebody uses
-                               // GET for wikitext parsing
+                       if (req.headers.cookie) {
+                               // Don't cache requests with a session.
                                apiUtils.setHeader(res, 'Cache-Control', 
'private,no-cache,s-maxage=0');
-
-                               if (metrics) {
-                                       metrics.endTiming('wt2html.wt.init',
-                                               
startTimers.get('wt2html.init'));
-                                       startTimers.set('wt2html.wt.parse', 
Date.now());
-                                       metrics.timing('wt2html.wt.size.input', 
wikitext.length);
-                               }
-                       } else if (oldid) {
-                               envOptions.pageWithOldid = true;
-
-                               if (req.headers.cookie) {
-                                       // Don't cache requests with a session.
-                                       apiUtils.setHeader(res, 
'Cache-Control', 'private,no-cache,s-maxage=0');
-                               }
-
-                               // Indicate the MediaWiki revision in a header 
as well for
-                               // ease of extraction in clients.
-                               apiUtils.setHeader(res, 'content-revision-id', 
oldid);
-
-                               if (metrics) {
-                                       
metrics.endTiming('wt2html.pageWithOldid.init',
-                                               
startTimers.get('wt2html.init'));
-                                       
startTimers.set('wt2html.pageWithOldid.parse', Date.now());
-                                       
metrics.timing('wt2html.pageWithOldid.size.input', env.page.src.length);
-                               }
-                       } else {
-                               console.assert(false, 'Should be unreachable');
                        }
 
-                       return parse({
-                               // NOTE: This causes another TemplateRequest 
but otherwise
-                               // we don't have all the metadata.
-                               input: (typeof wikitext === 'string') ? 
wikitext : undefined,
-                               mode: 'wt2html',
-                               parsoidOptions: parsoidOptions,
-                               envOptions: envOptions,
-                               oldid: oldid,
-                               contentmodel: opts.contentmodel,
-                               contentVersion: env.contentVersion,
-                               body_only: res.locals.body_only,
-                               cacheConfig: true,
-                               reuseExpansions: reuseExpansions,
-                       })
-                       .then(function(out) {
-                               if (opts.format === 'lint') {
-                                       apiUtils.jsonResponse(res, out.lint);
-                               } else {
-                                       apiUtils.wt2htmlRes(env, res, out.html, 
out.pb, out.contentmodel);
-                               }
-                               var html = out.html;
-                               if (metrics) {
-                                       if 
(startTimers.has('wt2html.wt.parse')) {
-                                               
metrics.endTiming('wt2html.wt.parse',
-                                                       
startTimers.get('wt2html.wt.parse'));
-                                               
metrics.timing('wt2html.wt.size.output', html.length);
-                                       } else if 
(startTimers.has('wt2html.pageWithOldid.parse')) {
-                                               
metrics.endTiming('wt2html.pageWithOldid.parse',
-                                                       
startTimers.get('wt2html.pageWithOldid.parse'));
-                                               
metrics.timing('wt2html.pageWithOldid.size.output', html.length);
-                                       }
-                                       metrics.endTiming('wt2html.total', 
startTimers.get('wt2html.total'));
-                               }
-                       });
+                       // Indicate the MediaWiki revision in a header as well 
for
+                       // ease of extraction in clients.
+                       apiUtils.setHeader(res, 'content-revision-id', oldid);
+
+                       if (metrics) {
+                               metrics.endTiming(
+                                       'wt2html.pageWithOldid.init',
+                                       startTimers.get('wt2html.init')
+                               );
+                               startTimers.set('wt2html.pageWithOldid.parse', 
Date.now());
+                               
metrics.timing('wt2html.pageWithOldid.size.input', env.page.src.length);
+                       }
+               } else {
+                       console.assert(false, 'Should be unreachable');
+               }
+
+               var out = yield parse({
+                       // NOTE: This causes another TemplateRequest but 
otherwise
+                       // we don't have all the metadata.
+                       input: (typeof wikitext === 'string') ? wikitext : 
undefined,
+                       mode: 'wt2html',
+                       parsoidOptions: parsoidOptions,
+                       envOptions: envOptions,
+                       oldid: oldid,
+                       contentmodel: opts.contentmodel,
+                       contentVersion: env.contentVersion,
+                       body_only: res.locals.body_only,
+                       cacheConfig: true,
+                       reuseExpansions: reuseExpansions,
                });
+               if (opts.format === 'lint') {
+                       apiUtils.jsonResponse(res, out.lint);
+               } else {
+                       apiUtils.wt2htmlRes(env, res, out.html, out.pb, 
out.contentmodel);
+               }
+               var html = out.html;
+               if (metrics) {
+                       if (startTimers.has('wt2html.wt.parse')) {
+                               metrics.endTiming(
+                                       'wt2html.wt.parse', 
startTimers.get('wt2html.wt.parse')
+                               );
+                               metrics.timing('wt2html.wt.size.output', 
html.length);
+                       } else if 
(startTimers.has('wt2html.pageWithOldid.parse')) {
+                               metrics.endTiming(
+                                       'wt2html.pageWithOldid.parse',
+                                       
startTimers.get('wt2html.pageWithOldid.parse')
+                               );
+                               
metrics.timing('wt2html.pageWithOldid.size.output', html.length);
+                       }
+                       metrics.endTiming('wt2html.total', 
startTimers.get('wt2html.total'));
+               }
        });
 
-       var html2wt = Promise.method(function(req, res, html) {
+       var html2wt = Promise.async(function *(req, res, html) {
                var env = res.locals.env;
                var opts = res.locals.opts;
 
@@ -517,7 +515,7 @@
                        selser = { oldtext: oldtext, oldhtml: oldhtml };
                }
 
-               return parse({
+               var out = yield parse({
                        input: DU.toXML(doc),
                        mode: useSelser ? 'selser' : 'html2wt',
                        parsoidOptions: parsoidOptions,
@@ -527,18 +525,19 @@
                        contentmodel: opts.contentmodel ||
                                (opts.original && opts.original.contentmodel),
                        cacheConfig: true,
-               })
-               .then(function(out) {
-                       if (metrics) {
-                               metrics.endTiming('html2wt.total',
-                                       startTimers.get('html2wt.total'));
-                               metrics.timing('html2wt.size.output', 
out.wt.length);
-                       }
-                       apiUtils.plainResponse(res, out.wt, undefined, 
apiUtils.wikitextContentType(env));
                });
+               if (metrics) {
+                       metrics.endTiming(
+                               'html2wt.total', 
startTimers.get('html2wt.total')
+                       );
+                       metrics.timing('html2wt.size.output', out.wt.length);
+               }
+               apiUtils.plainResponse(
+                       res, out.wt, undefined, 
apiUtils.wikitextContentType(env)
+               );
        });
 
-       var pb2pb = Promise.method(function(req, res) {
+       var pb2pb = Promise.async(function *(req, res) { // eslint-disable-line 
require-yield
                var env = res.locals.env;
                var opts = res.locals.opts;
 
@@ -591,15 +590,15 @@
        });
 
        // GET requests
-       routes.v3Get = function(req, res) {
+       routes.v3Get = Promise.async(function *(req, res) {
                var opts = res.locals.opts;
                var env = res.locals.env;
-               var p;
+
                if (opts.format === 'wikitext') {
-                       var target = env.normalizeAndResolvePageTitle();
-                       var oldid = res.locals.oldid;
-                       p = TemplateRequest.setPageSrcInfo(env, target, oldid)
-                       .then(function() {
+                       try {
+                               var target = env.normalizeAndResolvePageTitle();
+                               var oldid = res.locals.oldid;
+                               yield TemplateRequest.setPageSrcInfo(env, 
target, oldid);
                                if (!oldid) {
                                        return apiUtils.redirectToOldid(req, 
res);
                                }
@@ -607,18 +606,19 @@
                                        apiUtils.setHeader(res, 
'x-contentmodel', env.page.meta.revision.contentmodel);
                                }
                                apiUtils.plainResponse(res, env.page.src, 
undefined, apiUtils.wikitextContentType(env));
-                       });
+                       } catch (e) {
+                               apiUtils.errorHandler(env, e);
+                       }
                } else {
-                       p = wt2html(req, res);
+                       return apiUtils.errorWrapper(env, wt2html(req, res));
                }
-               return p.catch(apiUtils.errorHandler.bind(null, env));
-       };
+       });
 
        // POST requests
-       routes.v3Post = function(req, res) {
+       routes.v3Post = Promise.async(function *(req, res) { // 
eslint-disable-line require-yield
                var opts = res.locals.opts;
                var env = res.locals.env;
-               var p;
+
                if (opts.from === 'wikitext') {
                        // Accept wikitext as a string or object{body,headers}
                        var wikitext = opts.wikitext;
@@ -633,7 +633,7 @@
                        if (typeof wikitext !== 'string' && 
res.locals.titleMissing) {
                                return apiUtils.fatalRequest(env, 'No title or 
wikitext was provided.', 400);
                        }
-                       p = wt2html(req, res, wikitext);
+                       return apiUtils.errorWrapper(env, wt2html(req, res, 
wikitext));
                } else {
                        if (opts.format === 'wikitext') {
                                // html is required for serialization
@@ -643,13 +643,12 @@
                                // Accept html as a string or 
object{body,headers}
                                var html = (typeof opts.html === 'string') ?
                                        opts.html : (opts.html.body || '');
-                               p = html2wt(req, res, html);
+                               return apiUtils.errorWrapper(env, html2wt(req, 
res, html));
                        } else {
-                               p = pb2pb(req, res);
+                               return apiUtils.errorWrapper(env, pb2pb(req, 
res));
                        }
                }
-               return p.catch(apiUtils.errorHandler.bind(null, env));
-       };
+       });
 
        return routes;
 };

-- 
To view, visit https://gerrit.wikimedia.org/r/402436
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If181edf096861e31dc8d5fa20910fb8ab8a511d4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: C. Scott Ananian <canan...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to