1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-11-22 16:30:11 +00:00

Catch JSON syntax errors for all commands.

...and emit line/column info.
This commit is contained in:
hacksalot 2016-01-01 17:20:42 -05:00
parent 8c8dbfed72
commit 13fc903b2b
5 changed files with 49 additions and 20 deletions

View File

@ -32,6 +32,12 @@ Error-handling routines for HackMyResume.
err: function( ex, shouldExit ) { err: function( ex, shouldExit ) {
var msg = '', exitCode; var msg = '', exitCode;
if( ex.handled ) {
if( shouldExit )
process.exit( exitCode );
return;
}
if( ex.fluenterror ){ if( ex.fluenterror ){
switch( ex.fluenterror ) { // TODO: Remove magic numbers switch( ex.fluenterror ) { // TODO: Remove magic numbers

View File

@ -14,6 +14,7 @@ Definition of the ResumeFactory class.
var FS = require('fs'); var FS = require('fs');
var ResumeConverter = require('./convert'); var ResumeConverter = require('./convert');
var chalk = require('chalk'); var chalk = require('chalk');
var SyntaxErrorEx = require('../utils/syntax-error-ex');
@ -28,12 +29,13 @@ Definition of the ResumeFactory class.
/** /**
Load one or more resumes from disk. Load one or more resumes from disk.
*/ */
load: function ( sources, log, toFormat, objectify ) { load: function ( sources, opts ) {
// Loop over all inputs, parsing each to JSON and then to a FRESHResume // Loop over all inputs, parsing each to JSON and then to a FRESHResume
// or JRSResume object. // or JRSResume object.
var that = this; var that = this;
return sources.map( function( src ) { return sources.map( function( src ) {
return that.loadOne( src, log, toFormat, objectify ); return that.loadOne( src, opts );
}); });
}, },
@ -43,17 +45,21 @@ Definition of the ResumeFactory class.
/** /**
Load a single resume from disk. Load a single resume from disk.
*/ */
loadOne: function( src, log, toFormat, objectify ) { loadOne: function( src, opts ) {
var log = opts.log;
var toFormat = opts.format;
var objectify = opts.objectify;
// Get the destination format. Can be 'fresh', 'jrs', or null/undefined. // Get the destination format. Can be 'fresh', 'jrs', or null/undefined.
toFormat && (toFormat = toFormat.toLowerCase().trim()); toFormat && (toFormat = toFormat.toLowerCase().trim());
// Load and parse the resume JSON // Load and parse the resume JSON
var info = _parse( src, log, toFormat ); var info = _parse( src, opts );
if( info.error ) return info; if( info.error ) return info;
var json = info.json;
// Determine the resume format: FRESH or JRS // Determine the resume format: FRESH or JRS
var json = info.json;
var orgFormat = ( json.meta && json.meta.format && var orgFormat = ( json.meta && json.meta.format &&
json.meta.format.startsWith('FRESH@') ) ? json.meta.format.startsWith('FRESH@') ) ?
'fresh' : 'jrs'; 'fresh' : 'jrs';
@ -81,12 +87,12 @@ Definition of the ResumeFactory class.
function _parse( fileName, log, toFormat ) { function _parse( fileName, opts ) {
var rawData; var rawData;
try { try {
// TODO: Core should not log // TODO: Core should not log
log( chalk.gray('Reading resume: ') + chalk.cyan.bold(fileName) ); opts.log( chalk.gray('Reading resume: ') + chalk.cyan.bold(fileName) );
// Read the file // Read the file
rawData = FS.readFileSync( fileName, 'utf8' ); rawData = FS.readFileSync( fileName, 'utf8' );
@ -99,12 +105,18 @@ Definition of the ResumeFactory class.
} }
catch( ex ) { catch( ex ) {
// If FS.readFileSync threw, pass the exception along. // JSON.parse failed due to invalid JSON
if (!rawData) if ( ex instanceof SyntaxError) {
throw ex; var info = new SyntaxErrorEx( ex, rawData );
opts.log( chalk.red.bold(fileName.toUpperCase() + ' contains invalid JSON on line ' +
info.line + ' column ' + info.col + '.' +
chalk.red(' Unable to validate.')));
opts.log( chalk.red.bold('INTERNAL: ' + ex) );
ex.handled = true;
}
// Otherwise if JSON.parse failed: probably a SyntaxError. if( opts.throw ) throw ex;
return { else return {
error: ex, error: ex,
raw: rawData raw: rawData
}; };

View File

@ -23,7 +23,7 @@ Implementation of the 'convert' verb for HackMyResume.
if( sources && dst && sources.length && dst.length && sources.length !== dst.length ) { if( sources && dst && sources.length && dst.length && sources.length !== dst.length ) {
throw { fluenterror: 7 }; throw { fluenterror: 7 };
} }
var sourceResumes = ResumeFactory.load( sources, _log, null, true ); var sourceResumes = ResumeFactory.load( sources, { log: _log, format: null, objectify: true, throw: true } );
sourceResumes.forEach(function( src, idx ) { sourceResumes.forEach(function( src, idx ) {
var sheet = src.rez; var sheet = src.rez;
var sourceFormat = ((sheet.basics && sheet.basics.imp) || sheet.imp).orgFormat === 'JRS' ? 'JRS' : 'FRESH'; var sourceFormat = ((sheet.basics && sheet.basics.imp) || sheet.imp).orgFormat === 'JRS' ? 'JRS' : 'FRESH';

View File

@ -59,7 +59,9 @@ Implementation of the 'generate' verb for HackMyResume.
// Load input resumes... // Load input resumes...
if( !src || !src.length ) { throw { fluenterror: 3 }; } if( !src || !src.length ) { throw { fluenterror: 3 }; }
var sheets = ResumeFactory.load(src, _log, theme.render ? 'JRS' : 'FRESH', true); var sheets = ResumeFactory.load(src, {
log: _log, format: theme.render ? 'JRS' : 'FRESH', objectify: true, throw: true
});
// Merge input resumes... // Merge input resumes...
var msg = ''; var msg = '';

View File

@ -30,17 +30,26 @@ Implementation of the 'validate' verb for HackMyResume.
// Load input resumes... // Load input resumes...
sources.forEach(function( src ) { sources.forEach(function( src ) {
var result = ResumeFactory.loadOne( src, function(){}, null, false ); var result = ResumeFactory.loadOne( src, {
log: function(){},
format: null,
objectify: false,
throw: false
});
if( result.error ) { if( result.error ) {
_log( chalk.white('Validating ') + chalk.gray.bold(src) + chalk.white(' against ') + chalk.gray.bold('AUTO') + chalk.white(' schema:') + chalk.red.bold(' BROKEN') ); // TODO: Core should not log
_log( chalk.white('Validating ') + chalk.gray.bold(src) +
chalk.white(' against ') + chalk.gray.bold('AUTO') +
chalk.white(' schema:') + chalk.red.bold(' BROKEN') );
var ex = result.error; // alias var ex = result.error; // alias
if ( ex instanceof SyntaxError) { if ( ex instanceof SyntaxError) {
var info = new SyntaxErrorEx( ex, result.raw ); var info = new SyntaxErrorEx( ex, result.raw );
_log( chalk.red.bold('--> ') + chalk.red(src.toUpperCase() + ' contains invalid JSON on line ' + _log( chalk.red.bold('--> ' + src.toUpperCase() + ' contains invalid JSON on line ' +
info.line + ' column ' + info.col + '.') + info.line + ' column ' + info.col + '.' +
chalk.red(' Unable to validate.') ); chalk.red(' Unable to validate.') ) );
_log( chalk.red(' INTERNAL: ' + ex) ); _log( chalk.red.bold(' INTERNAL: ' + ex) );
} }
else { else {
_log(chalk.red.bold('ERROR: ' + ex.toString())); _log(chalk.red.bold('ERROR: ' + ex.toString()));