1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-07-05 01:20:06 +01:00

Improve error handling.

This commit is contained in:
hacksalot 2016-01-18 14:10:35 -05:00
parent c8d8e566f8
commit 3e3803ed85
9 changed files with 134 additions and 39 deletions

View File

@ -155,6 +155,10 @@ Error-handling routines for HackMyResume.
warn = false; warn = false;
break; break;
case HMSTATUS.generateError:
console.log(ex);
break;
case HMSTATUS.invalidFormat: case HMSTATUS.invalidFormat:
ex.data.forEach(function(d){ ex.data.forEach(function(d){
msg += printf( M2C( this.msgs.invalidFormat.msg, 'bold' ), msg += printf( M2C( this.msgs.invalidFormat.msg, 'bold' ),
@ -162,6 +166,12 @@ Error-handling routines for HackMyResume.
}, this); }, this);
break; break;
case HMSTATUS.invalidHelperUse:
msg = printf( M2C( this.msgs.invalidHelperUse.msg ), ex.helper );
quit = false;
warn = true;
break;
case HMSTATUS.notOnPath: case HMSTATUS.notOnPath:
msg = printf( M2C(this.msgs.notOnPath.msg, 'bold'), ex.engine); msg = printf( M2C(this.msgs.notOnPath.msg, 'bold'), ex.engine);
quit = false; quit = false;

View File

@ -26,7 +26,7 @@ events:
http-server <resume-folder> http-server <resume-folder>
For more information, see the README." For more information, see the README."
beforeGenerate: afterGenerate:
msg: msg:
- " (with %s)" - " (with %s)"
- "Skipping %s resume: %s" - "Skipping %s resume: %s"
@ -80,3 +80,5 @@ errors:
msg: Reading **???** resume: **%s** msg: Reading **???** resume: **%s**
parseError: parseError:
msg: Invalid or corrupt JSON on line %s column %s. msg: Invalid or corrupt JSON on line %s column %s.
invalidHelperUse:
msg: Invalid use of the **%s** theme helper.

View File

@ -127,22 +127,22 @@ Output routines for HackMyResume.
} }
break; break;
case HME.beforeGenerate: case HME.afterGenerate:
var suffix = ''; var suffix = '';
if( evt.fmt === 'pdf' ) { if( evt.fmt === 'pdf' ) {
if( this.opts.pdf ) { if( this.opts.pdf ) {
if( this.opts.pdf !== 'none' ) { if( this.opts.pdf !== 'none' ) {
suffix = printf( M2C( this.msgs.beforeGenerate.msg[0], 'green' ), this.opts.pdf ); suffix = printf( M2C( this.msgs.afterGenerate.msg[0], evt.error ? 'red' : 'green' ), this.opts.pdf );
} }
else { else {
L( M2C( this.msgs.beforeGenerate.msg[1], 'gray' ), L( M2C( this.msgs.afterGenerate.msg[1], 'gray' ),
evt.fmt.toUpperCase(), evt.file ); evt.fmt.toUpperCase(), evt.file );
return; return;
} }
} }
} }
L( M2C( this.msgs.beforeGenerate.msg[2] + suffix, 'green' ), L( M2C( this.msgs.afterGenerate.msg[2] + suffix, evt.error ? 'red' : 'green' ),
pad(evt.fmt.toUpperCase(),4,null,pad.RIGHT), pad(evt.fmt.toUpperCase(),4,null,pad.RIGHT),
PATH.relative(process.cwd(), evt.file )); PATH.relative(process.cwd(), evt.file ));
break; break;

View File

@ -24,7 +24,8 @@ Status codes for HackMyResume.
readError: 14, readError: 14,
parseError: 15, parseError: 15,
fileSaveError: 16, fileSaveError: 16,
generateError: 17 generateError: 17,
invalidHelperUse: 18
}; };
}()); }());

View File

@ -15,6 +15,7 @@ Definition of the TemplateGenerator class. TODO: Refactor
, PATH = require('path') , PATH = require('path')
, parsePath = require('parse-filepath') , parsePath = require('parse-filepath')
, MKDIRP = require('mkdirp') , MKDIRP = require('mkdirp')
, HMSTATUS = require('../core/status-codes')
, BaseGenerator = require( './base-generator' ) , BaseGenerator = require( './base-generator' )
, EXTEND = require('../utils/extend') , EXTEND = require('../utils/extend')
, FRESHTheme = require('../core/fresh-theme') , FRESHTheme = require('../core/fresh-theme')
@ -171,7 +172,7 @@ Definition of the TemplateGenerator class. TODO: Refactor
} }
catch( ex ) { catch( ex ) {
that.stat( HME.error, ex.fluenterrror || that.stat( HME.error, ex.fluenterrror ||
{ fluenterror: HACKMYSTATUS.fileSaveError, inner: ex } ); { fluenterror: HMSTATUS.fileSaveError, inner: ex } );
} }
} }
else if( file.info.action === null/* && theme.explicit*/ ) { else if( file.info.action === null/* && theme.explicit*/ ) {
@ -182,7 +183,7 @@ Definition of the TemplateGenerator class. TODO: Refactor
} }
catch( ex ) { catch( ex ) {
that.stat( HME.error, ex.fluenterrror || that.stat( HME.error, ex.fluenterrror ||
{ fluenterror: HACKMYSTATUS.fileSaveError, inner: ex } ); { fluenterror: HMSTATUS.fileSaveError, inner: ex } );
} }
} }
}); });
@ -276,13 +277,19 @@ Definition of the TemplateGenerator class. TODO: Refactor
file: tplInfo.css ? tplInfo.cssPath : null, file: tplInfo.css ? tplInfo.cssPath : null,
data: tplInfo.css || null data: tplInfo.css || null
}; };
return this.single( rez, tplInfo.data, this.format, cssInfo, this.opts, return this.single( rez, tplInfo.data, this.format, cssInfo, this.opts,
theme ); theme );
} }
catch(ex) { catch(ex) {
that.stat( HME.error, ex.fluenterrror || if( ex.fluenterror )
{ fluenterror: HACKMYSTATUS.generateError, inner: ex } ); throw ex;
else {
console.log('Ballyhoo');
console.log(ex.stack);
throw {
fluenterror: HMSTATUS.generateError, inner: ex
};
}
} }
} }

View File

@ -1,7 +1,7 @@
/** /**
Generic template helper definitions for HackMyResume / FluentCV. Generic template helper definitions for HackMyResume / FluentCV.
@license MIT. See LICENSE.md for details. @license MIT. See LICENSE.md for details.
@module generic-helpers.js @module helpers/generic-helpers
*/ */
@ -10,6 +10,8 @@ Generic template helper definitions for HackMyResume / FluentCV.
var MD = require('marked') var MD = require('marked')
, H2W = require('../utils/html-to-wpml') , H2W = require('../utils/html-to-wpml')
, XML = require('xml-escape') , XML = require('xml-escape')
, FluentDate = require('../core/fluent-date')
, HMSTATUS = require('../core/status-codes')
, moment = require('moment') , moment = require('moment')
, LO = require('lodash') , LO = require('lodash')
, _ = require('underscore') , _ = require('underscore')
@ -37,23 +39,21 @@ Generic template helper definitions for HackMyResume / FluentCV.
}, },
/** /**
Format a from/to date range. Given a resume sub-object with a start/end date, format a representation of
the date range.
@method dateRange @method dateRange
*/ */
dateRange: function( obj, fmt, sep, options ) { dateRange: function( obj, fmt, sep, fallback, options ) {
fmt = (fmt && String.is(fmt) && fmt) || 'YYYY-MM'; if( !obj ) return '';
sep = (sep && String.is(sep) && sep) || ' — '; return _fromTo( obj.start, obj.end, fmt, sep, fallback, options );
if( obj.safe ) { },
var dateA = (obj.safe.start && obj.safe.start.format(fmt)) || '';
var dateB = (obj.safe.end && obj.safe.end.format(fmt)) || ''; /**
if( obj.safe.start && obj.safe.end ) { Format a from/to date range for display.
return dateA + sep + dateB ; @method toFrom
} */
else if( obj.safe.start || obj.safe.end ) { fromTo: function() {
return dateA || dateB; return _fromTo.apply( this, arguments );
}
}
return '';
}, },
/** /**
@ -262,6 +262,65 @@ Generic template helper definitions for HackMyResume / FluentCV.
}; };
/**
Report an error to the outside world without throwing an exception. Currently
relies on kludging the running verb into. opts.
*/
function _reportError( code, params ) {
GenericHelpers.opts.errHandler.err( code, params );
}
/**
Format a from/to date range for display.
*/
function _fromTo( dateA, dateB, fmt, sep, fallback ) {
// Prevent accidental use of safe.start, safe.end, safe.date
// The dateRange helper is for raw dates only
if( moment.isMoment( dateA ) || moment.isMoment( dateB ) ) {
_reportError( HMSTATUS.invalidHelperUse, { helper: 'dateRange' } )
return '';
}
var dateFrom, dateTo, dateTemp;
// Check for 'current', 'present', 'now', '', null, and undefined
dateA = dateA || '';
dateB = dateB || '';
var dateATrim = dateA.trim().toLowerCase();
var dateBTrim = dateB.trim().toLowerCase();
var reserved = ['current','present','now', ''];
fmt = (fmt && String.is(fmt) && fmt) || 'YYYY-MM';
sep = (sep && String.is(sep) && sep) || ' — ';
if( _.contains( reserved, dateATrim )) {
dateFrom = fallback || '???';
}
else {
dateTemp = FluentDate.fmt( dateA );
dateFrom = dateTemp.format( fmt );
}
if( _.contains( reserved, dateBTrim )) {
dateTo = fallback || 'Current';
}
else {
dateTemp = FluentDate.fmt( dateB );
dateTo = dateTemp.format( fmt );
}
if( dateFrom && dateTo ) {
return dateFrom + sep + dateTo;
}
else if( dateFrom || dateTo ) {
return dateFrom || dateTo;
}
return '';
}
function skillLevelToIndex( lvl ) { function skillLevelToIndex( lvl ) {
var idx = 0; var idx = 0;
if( String.is( lvl ) ) { if( String.is( lvl ) ) {

View File

@ -15,9 +15,10 @@ Template helper definitions for Handlebars.
Register useful Handlebars helpers. Register useful Handlebars helpers.
@method registerHelpers @method registerHelpers
*/ */
module.exports = function( theme ) { module.exports = function( theme, opts ) {
helpers.theme = theme; helpers.theme = theme;
helpers.opts = opts;
HANDLEBARS.registerHelper( helpers ); HANDLEBARS.registerHelper( helpers );
}; };

View File

@ -32,7 +32,7 @@ Definition of the HandlebarsGenerator class.
generate: function( json, jst, format, cssInfo, opts, theme ) { generate: function( json, jst, format, cssInfo, opts, theme ) {
registerPartials( format, theme ); registerPartials( format, theme );
registerHelpers( theme ); registerHelpers( theme, opts );
// Preprocess text // Preprocess text
var encData = json; var encData = json;
@ -41,7 +41,7 @@ Definition of the HandlebarsGenerator class.
// Compile and run the Handlebars template. // Compile and run the Handlebars template.
var template = HANDLEBARS.compile(jst, { strict: false, assumeObjects: false }); var template = HANDLEBARS.compile(jst, { strict: false, assumeObjects: false });
return template({ return template({ // TODO: Clean
r: encData, r: encData,
RAW: json, RAW: json,
filt: opts.filters, filt: opts.filters,

View File

@ -157,6 +157,8 @@ Implementation of the 'build' verb for HackMyResume.
*/ */
function single( targInfo, theme, finished ) { function single( targInfo, theme, finished ) {
var ret, ex;
try { try {
if( !targInfo.fmt ) { if( !targInfo.fmt ) {
return; return;
@ -178,29 +180,42 @@ Implementation of the 'build' verb for HackMyResume.
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0]; function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists; MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
_opts.targets = finished; _opts.targets = finished;
return theFormat.gen.generate( rez, f, _opts ); _opts.errHandler = this;
ret = theFormat.gen.generate( rez, f, _opts );
} }
//Otherwise this is an ad-hoc format (JSON, YML, or PNG) that every theme //Otherwise this is an ad-hoc format (JSON, YML, or PNG) that every theme
// gets "for free". // gets "for free".
else { else {
theFormat = _fmts.filter( function(fmt) { theFormat = _fmts.filter( function(fmt) {
return fmt.name === targInfo.fmt.outFormat; return fmt.name === targInfo.fmt.outFormat;
})[0]; })[0];
var outFolder = PATH.dirname( f ); var outFolder = PATH.dirname( f );
MKDIRP.sync( outFolder ); // Ensure dest folder exists; MKDIRP.sync( outFolder ); // Ensure dest folder exists;
_opts.errHandler = this;
return theFormat.gen.generate( rez, f, _opts ); ret = theFormat.gen.generate( rez, f, _opts );
} }
} }
catch( ex ) { catch( e ) {
// Catch any errors caused by generating this file and don't let them // Catch any errors caused by generating this file and don't let them
// propagate -- typically we want to continue processing other formats // propagate -- typically we want to continue processing other formats
// even if this format failed. // even if this format failed.
this.err( HMEVENT.generate, { inner: ex } ); ex = e;
} }
this.stat( HMEVENT.afterGenerate, {
fmt: targInfo.fmt.outFormat,
file: PATH.relative( process.cwd(), f ),
error: ex
});
if( ex ) {
if( ex.fluenterror )
this.err( ex.fluenterror, ex );
else
this.err( HMSTATUS.generateError, { inner: ex } );
}
return ret;
} }