Arlolra has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/92923


Change subject: Better error handling in the ParserService
......................................................................

Better error handling in the ParserService

200b9eae019de50aa770c7fdf2daacb82c9080ce and
5cc3dfb83f6d2741be88a7f38e63f70dc6c63730 introduce some wonkiness.

Also, removed fetching the default pageinfo when no pagename is
supplied.

Change-Id: I2694f9f968a297f82294a54f1e1b2a75d66725eb
---
M js/api/ParserService.js
1 file changed, 70 insertions(+), 66 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid 
refs/changes/23/92923/1

diff --git a/js/api/ParserService.js b/js/api/ParserService.js
index 233528c..e422da9 100644
--- a/js/api/ParserService.js
+++ b/js/api/ParserService.js
@@ -275,10 +275,19 @@
        }
 };
 
-function handleCacheRequest (env, req, cb, err, src, cacheErr, cacheSrc) {
-       if (cacheErr) {
+function handleCacheRequest( env, req, res, cb, src, cacheErr, cacheSrc ) {
+       var newCb = function ( src, err, doc ) {
+               if ( err ) {
+                       env.errCB( err, true );
+                       return;
+               }
+               res.setHeader( 'Content-Type', 'text/html; charset=UTF-8' );
+               cb( req, res, src, doc );
+       };
+
+       if ( cacheErr ) {
                // No luck with the cache request, just proceed as normal.
-               Util.parse(env, cb, err, src);
+               Util.parse(env, newCb, null, src);
                return;
        }
        // Extract transclusion and extension content from the DOM
@@ -298,24 +307,14 @@
 
        // pass those expansions into Util.parse to prime the caches.
        //console.log('expansions:', expansions);
-       Util.parse(env, cb, null, src, expansions);
+       Util.parse(env, newCb, null, src, expansions);
 }
 
 var parse = function ( env, req, res, cb, err, src_and_metadata ) {
-       var newCb = function ( src, err, doc ) {
-               if ( err !== null ) {
-                       if ( !err.code ) {
-                               err.code = 500;
-                       }
-                       console.error( err.stack || err.toString() );
-                       res.setHeader('Content-Type', 'text/plain; 
charset=UTF-8');
-                       res.send( err.stack || err.toString(), err.code );
-                       return;
-               } else {
-                       res.setHeader('Content-Type', 'text/html; 
charset=UTF-8');
-                       cb( req, res, src, doc );
-               }
-       };
+       if ( err ) {
+               env.errCB( err, true )
+               return;
+       }
 
        // Set the source
        env.setPageSrcInfo( src_and_metadata );
@@ -324,7 +323,7 @@
        // env.page.meta.revision.parentid has the predecessor oldid
 
        // See if we can reuse transclusion or extension expansions.
-       if (!err && env.conf.parsoid.parsoidCacheURI &&
+       if (env.conf.parsoid.parsoidCacheURI &&
                        // Don't enter an infinite request loop.
                        ! /only-if-cached/.test(req.headers['cache-control']))
        {
@@ -339,9 +338,9 @@
                        cacheRequest = new libtr.ParsoidCacheRequest(env,
                                env.page.meta.title, cacheID);
                cacheRequest.once('src',
-                               handleCacheRequest.bind(null, env, req, newCb, 
err, env.page.src));
+                               handleCacheRequest.bind(null, env, req, res, 
cb, env.page.src));
        } else {
-               handleCacheRequest(env, req, newCb, err, env.page.src, 
"Recursive request", null);
+               handleCacheRequest(env, req, res, cb, env.page.src, "Recursive 
request", null);
        }
 };
 
@@ -374,23 +373,33 @@
        res.end('</body></html>');
 });
 
-function ParserError( msg, stack, code ) {
-       Error.call( this, msg );
+function EnvError( message, stack, code, restart ) {
+       this.message = message;
        this.stack = stack;
        this.code = code;
+       this.restart = restart;
 }
 
+EnvError.prototype = Object.create(Error.prototype, {
+       name: { value: "EnvError" },
+       constructor: { value: EnvError }
+});
+
 function errorHandler( err, req, res, next ) {
-       if ( !(err instanceof ParserError) ) {
+       if ( !(err instanceof EnvError) ) {
                return next( err );
        }
 
-       console.error( 'ERROR in ' + res.locals.iwp + ':' + res.locals.pageName 
+ ':\n' + err.message );
-       console.error( "Stack trace: " + err.stack );
+       res.setHeader( 'Content-Type', 'text/plain; charset=UTF-8' );
        res.send( err.stack, err.code );
 
-       // Force a clean restart of this worker
-       process.exit( 1 );
+       console.error( 'ERROR in ' + res.locals.iwp + ':' + res.locals.pageName 
);
+       console.error( 'Stack trace: ' + err.stack );
+
+       if ( err.restart ) {
+               // Force a clean restart of this worker
+               process.exit( 1 );
+       }
 }
 
 app.use( errorHandler );
@@ -409,11 +418,12 @@
 
 function parserEnvMw( req, res, next ) {
        MWParserEnvironment.getParserEnv( parsoidConfig, null, res.locals.iwp, 
res.locals.pageName, req.headers.cookie, function ( err, env ) {
-               env.errCB = function ( e ) {
-                       e = new ParserError(
+               env.errCB = function ( e, dontRestart ) {
+                       e = new EnvError(
                                e.message,
                                e.stack || e.toString(),
-                               e.code || 500
+                               e.code || 500,
+                               !dontRestart  // default to restarting
                        );
                        next( e );
                };
@@ -485,16 +495,11 @@
 // Round-trip article testing
 app.get( new RegExp('/_rt/(' + getInterwikiRE() + ')/(.*)'), interParams, 
parserEnvMw, function(req, res) {
        var env = res.locals.env;
-       req.connection.setTimeout(300 * 1000);
-
-       if ( env.page.name === 'favicon.ico' ) {
-               res.send( 'no favicon yet..', 404 );
-               return;
-       }
-
        var target = env.resolveTitle( env.normalizeTitle( env.page.name ), '' 
);
 
+       req.connection.setTimeout(300 * 1000);
        console.log('starting parsing of ' + target);
+
        var oldid = null;
        if ( req.query.oldid ) {
                oldid = req.query.oldid;
@@ -507,11 +512,6 @@
 // simulation
 app.get( new RegExp('/_rtve/(' + getInterwikiRE() + ')/(.*)'), interParams, 
parserEnvMw, function(req, res) {
        var env = res.locals.env;
-       if ( env.page.name === 'favicon.ico' ) {
-               res.send( 'no favicon yet..', 404 );
-               return;
-       }
-
        var target = env.resolveTitle( env.normalizeTitle( env.page.name ), '' 
);
 
        console.log('starting parsing of ' + target);
@@ -533,11 +533,6 @@
 // Round-trip article testing with selser over re-parsed HTML.
 app.get( new RegExp('/_rtselser/(' + getInterwikiRE() + ')/(.*)'), 
interParams, parserEnvMw, function (req, res) {
        var env = res.locals.env;
-       if ( env.page.name === 'favicon.ico' ) {
-               res.send( 'no favicon yet..', 404 );
-               return;
-       }
-
        var target = env.resolveTitle( env.normalizeTitle( env.page.name ), '' 
);
 
        console.log( 'starting parsing of ' + target );
@@ -620,20 +615,21 @@
        var tmpCb, oldid = null;
        if ( wt ) {
                wt = wt.replace( /\r/g, '' );
+
+               var parser = Util.getParserPipeline( env, 
'text/x-mediawiki/full' );
+               parser.on( 'document', function ( document ) {
+                       res.setHeader( 'Content-Type', 'text/html; 
charset=UTF-8' );
+                       // Don't cache requests when wt is set in case somebody 
uses
+                       // GET for wikitext parsing
+                       res.setHeader( 'Cache-Control', 
'private,no-cache,s-maxage=0' );
+                       sendRes( req.body.body ? document.body : document );
+               });
+
                tmpCb = function ( err, src_and_metadata ) {
                        if ( err ) {
-                               env.errCB( err );
+                               env.errCB( err, true );
                                return;
                        }
-
-                       var parser = Util.getParserPipeline( env, 
'text/x-mediawiki/full' );
-                       parser.on( 'document', function ( document ) {
-                               res.setHeader( 'Content-Type', 'text/html; 
charset=UTF-8' );
-                               // Don't cache requests when wt is set in case 
somebody uses
-                               // GET for wikitext parsing
-                               res.setHeader( 'Cache-Control', 
'private,no-cache,s-maxage=0' );
-                               sendRes( req.body.body ? document.body : 
document );
-                       });
 
                        // Set the source
                        env.setPageSrcInfo( src_and_metadata );
@@ -641,10 +637,17 @@
                        try {
                                parser.processToplevelDoc( wt );
                        } catch ( e ) {
-                               env.errCB( e );
+                               env.errCB( e, true );
                                return;
                        }
                };
+
+               if ( !res.locals.pageName ) {
+                       // no pageName supplied; don't fetch templates
+                       tmpCb( null, wt );
+                       return;
+               }
+
        } else {
                if ( req.query.oldid ) {
                        oldid = req.query.oldid;
@@ -662,7 +665,7 @@
                        res.setHeader( 'Cache-Control', 
'private,no-cache,s-maxage=0' );
                        tmpCb = function ( err, src_and_metadata ) {
                                if ( err ) {
-                                       env.errCB( err );
+                                       env.errCB( err, true );
                                        return;
                                }
 
@@ -670,7 +673,12 @@
                                env.setPageSrcInfo( src_and_metadata );
 
                                // Redirect to oldid
-                               res.redirect( req.path + "?oldid=" + 
env.page.meta.revision.revid );
+                               var url = [ "",
+                                       prefix,
+                                       target,
+                                       "?oldid=" + env.page.meta.revision.revid
+                               ].join( "/" );
+                               res.redirect( url );
                                console.warn( "redirected " + prefix + ':' + 
target + " to revision " + env.page.meta.revision.revid );
                        };
                }
@@ -689,8 +697,6 @@
 
 // Regular article parsing
 app.get( new RegExp( '/(' + getInterwikiRE() + ')/(.*)' ), interParams, 
parserEnvMw, function(req, res) {
-       var env = res.locals.env;
-
        // TODO gwicke: re-enable this when actually using Varnish
        //if (/only-if-cached/.test(req.headers['cache-control'])) {
        //      res.send( 'Clearly not cached since this request reached 
Parsoid. Please fix Varnish.',
@@ -703,14 +709,12 @@
 
 // Regular article serialization using POST
 app.post( new RegExp( '/(' + getInterwikiRE() + ')/(.*)' ), interParams, 
parserEnvMw, function ( req, res ) {
-
        // parse html or wt
        if ( req.body.wt ) {
                wt2html( req, res, req.body.wt );
        } else {
-               html2wt( req, res, req.body.html ? req.body.html : 
req.body.content );
+               html2wt( req, res, req.body.html ? req.body.html : ( 
req.body.content || '' ) );
        }
-
 });
 
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2694f9f968a297f82294a54f1e1b2a75d66725eb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to