mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-22 08:20:11 +00:00
Improve error handling.
This commit is contained in:
parent
3e3803ed85
commit
c98d05270e
@ -59,8 +59,10 @@ Error-handling routines for HackMyResume.
|
|||||||
));
|
));
|
||||||
|
|
||||||
// Output the stack (sometimes)
|
// Output the stack (sometimes)
|
||||||
if( objError.showStack )
|
if( objError.withStack ) {
|
||||||
o( chalk.red( ex.stack || ex.inner.stack ) );
|
var stack = ex.stack || (ex.inner && ex.inner.stack);
|
||||||
|
stack && o( chalk.red( stack ) );
|
||||||
|
}
|
||||||
|
|
||||||
// Quit if necessary
|
// Quit if necessary
|
||||||
if( objError.quit ) {
|
if( objError.quit ) {
|
||||||
@ -101,6 +103,7 @@ Error-handling routines for HackMyResume.
|
|||||||
function assembleError( ex ) {
|
function assembleError( ex ) {
|
||||||
|
|
||||||
var msg = '', withStack = false, isError = false, quit = true, warn = true;
|
var msg = '', withStack = false, isError = false, quit = true, warn = true;
|
||||||
|
if( this.debug ) withStack = true;
|
||||||
|
|
||||||
switch( ex.fluenterror ) {
|
switch( ex.fluenterror ) {
|
||||||
|
|
||||||
@ -156,7 +159,15 @@ Error-handling routines for HackMyResume.
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HMSTATUS.generateError:
|
case HMSTATUS.generateError:
|
||||||
console.log(ex);
|
msg = (ex.inner && ex.inner.toString()) || ex;
|
||||||
|
quit = false;
|
||||||
|
warn = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HMSTATUS.fileSaveError:
|
||||||
|
msg = printf( M2C( this.msgs.fileSaveError.msg ), (ex.inner || ex).toString() );
|
||||||
|
warn = false;
|
||||||
|
quit = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HMSTATUS.invalidFormat:
|
case HMSTATUS.invalidFormat:
|
||||||
@ -184,6 +195,11 @@ Error-handling routines for HackMyResume.
|
|||||||
warn = false;
|
warn = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HMSTATUS.mixedMerge:
|
||||||
|
msg = M2C( this.msgs.mixedMerge.msg );
|
||||||
|
quit = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case HMSTATUS.parseError:
|
case HMSTATUS.parseError:
|
||||||
if( SyntaxErrorEx.is( ex.inner )) {
|
if( SyntaxErrorEx.is( ex.inner )) {
|
||||||
var se = new SyntaxErrorEx( ex, ex.raw );
|
var se = new SyntaxErrorEx( ex, ex.raw );
|
||||||
|
@ -82,3 +82,7 @@ errors:
|
|||||||
msg: Invalid or corrupt JSON on line %s column %s.
|
msg: Invalid or corrupt JSON on line %s column %s.
|
||||||
invalidHelperUse:
|
invalidHelperUse:
|
||||||
msg: Invalid use of the **%s** theme helper.
|
msg: Invalid use of the **%s** theme helper.
|
||||||
|
fileSaveError:
|
||||||
|
msg: An error occurred while writing %s to disk: %s.
|
||||||
|
mixedMerge:
|
||||||
|
msg: "**Warning:** merging mixed resume types. Errors may occur."
|
||||||
|
@ -97,13 +97,16 @@ Output routines for HackMyResume.
|
|||||||
msg += printf(
|
msg += printf(
|
||||||
((idx === 0) ?
|
((idx === 0) ?
|
||||||
this.msgs.beforeMerge.msg[0] :
|
this.msgs.beforeMerge.msg[0] :
|
||||||
this.msgs.beforeMerge.msg[1] ), a.i().file
|
this.msgs.beforeMerge.msg[1] ), a.file
|
||||||
);
|
);
|
||||||
}, this);
|
}, this);
|
||||||
L( M2C(msg, 'green') );
|
L( M2C(msg, evt.mixed ? 'yellow' : 'green') );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HME.afterMerge:
|
case HME.afterMerge:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HME.applyTheme:
|
||||||
var numFormats = Object.keys( this.theme.formats ).length;
|
var numFormats = Object.keys( this.theme.formats ).length;
|
||||||
L( M2C(this.msgs.afterMerge.msg, 'green'),
|
L( M2C(this.msgs.afterMerge.msg, 'green'),
|
||||||
this.theme.name.toUpperCase(),
|
this.theme.name.toUpperCase(),
|
||||||
|
@ -25,7 +25,8 @@ Status codes for HackMyResume.
|
|||||||
parseError: 15,
|
parseError: 15,
|
||||||
fileSaveError: 16,
|
fileSaveError: 16,
|
||||||
generateError: 17,
|
generateError: 17,
|
||||||
invalidHelperUse: 18
|
invalidHelperUse: 18,
|
||||||
|
mixedMerge: 19
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -15,7 +15,6 @@ 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')
|
||||||
@ -102,12 +101,13 @@ Definition of the TemplateGenerator class. TODO: Refactor
|
|||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
// "Generate": process individual files within the theme
|
// "Generate": process individual files within the theme
|
||||||
|
// The transform() method catches exceptions internally
|
||||||
return {
|
return {
|
||||||
files: curFmt.files.map( function( tplInfo ) {
|
files: curFmt.files.map( function( tplInfo ) {
|
||||||
return {
|
return {
|
||||||
info: tplInfo,
|
info: tplInfo,
|
||||||
data: tplInfo.action === 'transform' ?
|
data: tplInfo.action === 'transform' ?
|
||||||
transform.call( that, rez, tplInfo, theme ) : undefined
|
transform.call( that, rez, tplInfo, theme, opts ) : undefined
|
||||||
};
|
};
|
||||||
}).filter(function(item){ return item !== null; }),
|
}).filter(function(item){ return item !== null; }),
|
||||||
themeInfo: themeInfo
|
themeInfo: themeInfo
|
||||||
@ -153,38 +153,26 @@ Definition of the TemplateGenerator class. TODO: Refactor
|
|||||||
|
|
||||||
if( file.info.action === 'transform' ) {
|
if( file.info.action === 'transform' ) {
|
||||||
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
||||||
try {
|
if( that.onBeforeSave ) {
|
||||||
if( that.onBeforeSave ) {
|
file.data = that.onBeforeSave({
|
||||||
file.data = that.onBeforeSave({
|
theme: theme,
|
||||||
theme: theme,
|
outputFile: (file.info.major ? f : thisFilePath),
|
||||||
outputFile: (file.info.major ? f : thisFilePath),
|
mk: file.data,
|
||||||
mk: file.data,
|
opts: that.opts
|
||||||
opts: that.opts
|
});
|
||||||
});
|
if( !file.data ) return; // PDF etc
|
||||||
if( !file.data ) return; // PDF etc
|
|
||||||
}
|
|
||||||
var fileName = file.info.major ? f : thisFilePath;
|
|
||||||
MKDIRP.sync( PATH.dirname( fileName ) );
|
|
||||||
FS.writeFileSync( fileName, file.data,
|
|
||||||
{ encoding: 'utf8', flags: 'w' } );
|
|
||||||
that.onAfterSave && that.onAfterSave(
|
|
||||||
{ outputFile: fileName, mk: file.data, opts: that.opts } );
|
|
||||||
}
|
|
||||||
catch( ex ) {
|
|
||||||
that.stat( HME.error, ex.fluenterrror ||
|
|
||||||
{ fluenterror: HMSTATUS.fileSaveError, inner: ex } );
|
|
||||||
}
|
}
|
||||||
|
var fileName = file.info.major ? f : thisFilePath;
|
||||||
|
MKDIRP.sync( PATH.dirname( fileName ) );
|
||||||
|
FS.writeFileSync( fileName, file.data,
|
||||||
|
{ encoding: 'utf8', flags: 'w' } );
|
||||||
|
that.onAfterSave && that.onAfterSave(
|
||||||
|
{ outputFile: fileName, mk: file.data, opts: that.opts } );
|
||||||
}
|
}
|
||||||
else if( file.info.action === null/* && theme.explicit*/ ) {
|
else if( file.info.action === null/* && theme.explicit*/ ) {
|
||||||
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
||||||
try {
|
MKDIRP.sync( PATH.dirname(thisFilePath) );
|
||||||
MKDIRP.sync( PATH.dirname(thisFilePath) );
|
FS.copySync( file.info.path, thisFilePath );
|
||||||
FS.copySync( file.info.path, thisFilePath );
|
|
||||||
}
|
|
||||||
catch( ex ) {
|
|
||||||
that.stat( HME.error, ex.fluenterrror ||
|
|
||||||
{ fluenterror: HMSTATUS.fileSaveError, inner: ex } );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -271,7 +259,7 @@ Definition of the TemplateGenerator class. TODO: Refactor
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function transform( rez, tplInfo, theme ) {
|
function transform( rez, tplInfo, theme, opts ) {
|
||||||
try {
|
try {
|
||||||
var cssInfo = {
|
var cssInfo = {
|
||||||
file: tplInfo.css ? tplInfo.cssPath : null,
|
file: tplInfo.css ? tplInfo.cssPath : null,
|
||||||
@ -281,15 +269,8 @@ Definition of the TemplateGenerator class. TODO: Refactor
|
|||||||
theme );
|
theme );
|
||||||
}
|
}
|
||||||
catch(ex) {
|
catch(ex) {
|
||||||
if( ex.fluenterror )
|
if( opts.errHandler ) opts.errHandler(ex);
|
||||||
throw ex;
|
else throw ex;
|
||||||
else {
|
|
||||||
console.log('Ballyhoo');
|
|
||||||
console.log(ex.stack);
|
|
||||||
throw {
|
|
||||||
fluenterror: HMSTATUS.generateError, inner: ex
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
|
|||||||
// Prevent accidental use of safe.start, safe.end, safe.date
|
// Prevent accidental use of safe.start, safe.end, safe.date
|
||||||
// The dateRange helper is for raw dates only
|
// The dateRange helper is for raw dates only
|
||||||
if( moment.isMoment( dateA ) || moment.isMoment( dateB ) ) {
|
if( moment.isMoment( dateA ) || moment.isMoment( dateB ) ) {
|
||||||
_reportError( HMSTATUS.invalidHelperUse, { helper: 'dateRange' } )
|
_reportError( HMSTATUS.invalidHelperUse, { helper: 'dateRange' } );
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ Implementation of the 'build' verb for HackMyResume.
|
|||||||
, pad = require('string-padding')
|
, pad = require('string-padding')
|
||||||
, Verb = require('../verbs/verb');
|
, Verb = require('../verbs/verb');
|
||||||
|
|
||||||
var _err, _log, rez;
|
var _err, _log, _rezObj;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -65,50 +65,62 @@ Implementation of the 'build' verb for HackMyResume.
|
|||||||
*/
|
*/
|
||||||
function build( src, dst, opts ) {
|
function build( src, dst, opts ) {
|
||||||
|
|
||||||
|
|
||||||
if( !src || !src.length ) { this.err( HMSTATUS.resumeNotFound ); }
|
if( !src || !src.length ) { this.err( HMSTATUS.resumeNotFound ); }
|
||||||
|
|
||||||
prep( src, dst, opts );
|
prep( src, dst, opts );
|
||||||
|
|
||||||
// Load input resumes...
|
// Load input resumes as JSON...
|
||||||
var sheets = ResumeFactory.load(src, {
|
var sheetObjects = ResumeFactory.load(src, {
|
||||||
format: null, objectify: true, throw: true, inner: { sort: _opts.sort }
|
format: null, objectify: false, throw: true, inner: { sort: _opts.sort }
|
||||||
}, this).map( function(sh) {
|
}, this);
|
||||||
return sh.rez;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load the theme...we do this first because the theme choice (FRESH or
|
var sheets = sheetObjects.map(function(r) { return r.json; });
|
||||||
// JSON Resume) determines what format we'll convert the resume to.
|
|
||||||
|
// Load the theme...
|
||||||
this.stat( HMEVENT.beforeTheme, { theme: _opts.theme });
|
this.stat( HMEVENT.beforeTheme, { theme: _opts.theme });
|
||||||
var tFolder = verifyTheme.call( this, _opts.theme );
|
var tFolder = verifyTheme.call( this, _opts.theme );
|
||||||
var theme = loadTheme( tFolder );
|
var theme = loadTheme( tFolder );
|
||||||
this.stat( HMEVENT.afterTheme, { theme: theme });
|
this.stat( HMEVENT.afterTheme, { theme: theme });
|
||||||
|
|
||||||
// Check for invalid outputs
|
// Check for invalid outputs...
|
||||||
var inv = verifyOutputs.call( this, dst, theme );
|
var inv = verifyOutputs.call( this, dst, theme );
|
||||||
if( inv && inv.length ) {
|
if( inv && inv.length ) {
|
||||||
this.err( HMSTATUS.invalidFormat, { data: inv, theme: theme } );
|
this.err( HMSTATUS.invalidFormat, { data: inv, theme: theme } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert resume inputs as necessary
|
// Merge input resumes, yielding a single source resume.
|
||||||
var toFormat = theme.render ? 'JRS' : 'FRESH';
|
var rez;
|
||||||
sheets.forEach( function( sh, idx ) {
|
if( sheets.length > 1 ) {
|
||||||
if( sh.format() !== toFormat ) {
|
|
||||||
this.stat( HMEVENT.beforeInlineConvert );
|
|
||||||
sheets[ idx ] = new (RTYPES[ toFormat ])();
|
|
||||||
var convJSON = RConverter[ 'to' + toFormat ]( sh );
|
|
||||||
sheets[ idx ].parseJSON( convJSON );
|
|
||||||
this.stat( HMEVENT.afterInlineConvert, { file: sh.i().file, fmt: toFormat } );
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Merge input resumes...
|
var isFRESH = !sheets[0].basics;
|
||||||
(sheets.length > 1) && this.stat( HMEVENT.beforeMerge, { f: _.clone(sheets) });
|
var mixed = _.any( sheets, function(s) { return isFRESH ? s.basics : !s.basics; });
|
||||||
rez = _.reduceRight( sheets, function( a, b, idx ) {
|
this.stat( HMEVENT.beforeMerge, { f: _.clone(sheetObjects), mixed: mixed });
|
||||||
return extend( true, b, a );
|
if( mixed ) {
|
||||||
});
|
this.err( HMSTATUS.mixedMerge );
|
||||||
// TODO: Fix this condition
|
}
|
||||||
(sheets.length) && this.stat( HMEVENT.afterMerge, { r: rez } );
|
rez = _.reduceRight( sheets, function( a, b, idx ) {
|
||||||
|
return extend( true, b, a );
|
||||||
|
});
|
||||||
|
this.stat( HMEVENT.afterMerge, { r: rez } );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rez = sheets[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stat( HMEVENT.applyTheme, { r: rez });
|
||||||
|
|
||||||
|
|
||||||
|
// Convert the merged source resume to the theme's format, if necessary
|
||||||
|
var orgFormat = rez.basics ? 'JRS' : 'FRESH';
|
||||||
|
var toFormat = theme.render ? 'JRS' : 'FRESH';
|
||||||
|
if( toFormat !== orgFormat ) {
|
||||||
|
this.stat( HMEVENT.beforeInlineConvert );
|
||||||
|
rez = RConverter[ 'to' + toFormat ]( rez );
|
||||||
|
this.stat( HMEVENT.afterInlineConvert, { file: sheetObjects[0].file, fmt: toFormat });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the resume into a FRESHResume or JRSResume object
|
||||||
|
_rezObj = new (RTYPES[ toFormat ])().parseJSON( rez );
|
||||||
|
|
||||||
// Expand output resumes...
|
// Expand output resumes...
|
||||||
var targets = expand( dst, theme );
|
var targets = expand( dst, theme );
|
||||||
@ -148,6 +160,10 @@ Implementation of the 'build' verb for HackMyResume.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleInternalError( ex ) {
|
||||||
|
console.log(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generate a single target resume such as "out/rez.html" or "out/rez.doc".
|
Generate a single target resume such as "out/rez.html" or "out/rez.doc".
|
||||||
@ -157,14 +173,12 @@ Implementation of the 'build' verb for HackMyResume.
|
|||||||
*/
|
*/
|
||||||
function single( targInfo, theme, finished ) {
|
function single( targInfo, theme, finished ) {
|
||||||
|
|
||||||
var ret, ex;
|
var ret, ex, f = targInfo.file;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if( !targInfo.fmt ) {
|
|
||||||
return;
|
if( !targInfo.fmt ) { return; }
|
||||||
}
|
var fType = targInfo.fmt.outFormat
|
||||||
var f = targInfo.file
|
|
||||||
, fType = targInfo.fmt.outFormat
|
|
||||||
, fName = PATH.basename(f, '.' + fType)
|
, fName = PATH.basename(f, '.' + fType)
|
||||||
, theFormat;
|
, theFormat;
|
||||||
|
|
||||||
@ -180,8 +194,8 @@ 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;
|
||||||
_opts.errHandler = this;
|
_opts.errHandler = handleInternalError;
|
||||||
ret = theFormat.gen.generate( rez, f, _opts );
|
ret = theFormat.gen.generate( _rezObj, 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".
|
||||||
@ -191,8 +205,8 @@ Implementation of the 'build' verb for HackMyResume.
|
|||||||
})[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;
|
_opts.errHandler = handleInternalError;
|
||||||
ret = theFormat.gen.generate( rez, f, _opts );
|
ret = theFormat.gen.generate( _rezObj, f, _opts );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( e ) {
|
catch( e ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user