1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-09-29 04:29:12 +01:00
HackMyResume/src/cli/error.coffee

222 lines
6.2 KiB
CoffeeScript
Raw Normal View History

2016-01-26 15:58:10 +00:00
###*
Error-handling routines for HackMyResume.
@module cli/error
@license MIT. See LICENSE.md for details.
###
2016-01-27 10:29:26 +00:00
HMSTATUS = require('../hmc/dist/core/status-codes')
2016-01-26 15:58:10 +00:00
PKG = require('../../package.json')
FS = require('fs')
2016-01-27 10:29:26 +00:00
FCMD = require('../hmc')
2016-01-26 15:58:10 +00:00
PATH = require('path')
WRAP = require('word-wrap')
2016-01-27 10:29:26 +00:00
M2C = require('../hmc/dist/utils/md2chalk.js')
2016-01-26 15:58:10 +00:00
chalk = require('chalk')
extend = require('extend')
YAML = require('yamljs')
printf = require('printf')
2016-01-27 10:29:26 +00:00
SyntaxErrorEx = require('../hmc/dist/utils/syntax-error-ex')
2016-01-26 15:58:10 +00:00
require('string.prototype.startswith')
###*
Error handler for HackMyResume. All errors are handled here.
@class ErrorHandler
###
ErrorHandler = module.exports =
init: ( debug, assert, silent ) ->
@debug = debug
@assert = assert
@silent = silent
@msgs = require('./msg').errors
@
err: ( ex, shouldExit ) ->
# Short-circuit logging output if --silent is on
o = if this.silent then () -> else _defaultLog
# Special case; can probably be removed.
throw ex if ex.pass
# Load error messages
@msgs = @msgs || require('./msg').errors
# Handle packaged HMR exceptions
if ex.fluenterror
# Output the error message
objError = assembleError.call @, ex
o( this[ 'format_' + objError.etype ]( objError.msg ))
# Output the stack (sometimes)
if objError.withStack
stack = ex.stack || (ex.inner && ex.inner.stack);
stack && o( chalk.gray( stack ) );
# Quit if necessary
if ex.quit || objError.quit
if @debug
o chalk.cyan('Exiting with error code ' + ex.fluenterror.toString())
if this.assert
ex.pass = true
throw ex
process.exit ex.fluenterror
# Handle raw exceptions
else
o( ex )
stackTrace = ex.stack || (ex.inner && ex.inner.stack)
if stackTrace && this.debug
o( M2C(ex.stack || ex.inner.stack, 'gray') )
format_error: ( msg ) ->
msg = msg || ''
chalk.red.bold( if msg.toUpperCase().startsWith('ERROR:') then msg else 'Error: ' + msg )
format_warning: ( brief, msg ) ->
chalk.yellow(brief) + chalk.yellow(msg || '')
format_custom: ( msg ) -> msg
_defaultLog = () -> console.log.apply console.log, arguments
assembleError = ( ex ) ->
msg = ''
withStack = false
quit = false
etype = 'warning'
withStack = true if @debug
switch ex.fluenterror
when HMSTATUS.themeNotFound
msg = printf( M2C( this.msgs.themeNotFound.msg, 'yellow' ), ex.data)
when HMSTATUS.copyCSS
msg = M2C( this.msgs.copyCSS.msg, 'red' )
quit = false
when HMSTATUS.resumeNotFound
msg = M2C( this.msgs.resumeNotFound.msg, 'yellow' );
when HMSTATUS.missingCommand
msg = M2C( this.msgs.missingCommand.msg + " (", 'yellow');
msg += Object.keys( FCMD.verbs ).map( (v, idx, ar) ->
return ( if idx == ar.length - 1 then chalk.yellow('or ') else '') +
chalk.yellow.bold(v.toUpperCase());
).join( chalk.yellow(', ')) + chalk.yellow(").\n\n");
msg += chalk.gray(FS.readFileSync(
PATH.resolve(__dirname, '../cli/use.txt'), 'utf8' ))
when HMSTATUS.invalidCommand
msg = printf( M2C( this.msgs.invalidCommand.msg, 'yellow'), ex.attempted )
when HMSTATUS.resumeNotFoundAlt
msg = M2C( this.msgs.resumeNotFoundAlt.msg, 'yellow' )
when HMSTATUS.inputOutputParity
msg = M2C( this.msgs.inputOutputParity.msg )
when HMSTATUS.createNameMissing
msg = M2C( this.msgs.createNameMissing.msg )
when HMSTATUS.pdfGeneration
msg = M2C( this.msgs.pdfGeneration.msg, 'bold' )
msg += chalk.red('\n' + ex.inner) if ex.inner
withStack = true
quit = false
etype = 'error'
when HMSTATUS.invalid
msg = M2C( this.msgs.invalid.msg, 'red' )
etype = 'error'
when HMSTATUS.generateError
msg = (ex.inner && ex.inner.toString()) || ex
quit = false
etype = 'error'
when HMSTATUS.fileSaveError
msg = printf( M2C( this.msgs.fileSaveError.msg ), (ex.inner || ex).toString() )
etype = 'error'
quit = false
when HMSTATUS.invalidFormat
ex.data.forEach( (d) ->
msg += printf( M2C( this.msgs.invalidFormat.msg, 'bold' ),
ex.theme.name.toUpperCase(), d.format.toUpperCase())
, @);
when HMSTATUS.missingParam
msg = printf(M2C( this.msgs.missingParam.msg ), ex.expected, ex.helper)
when HMSTATUS.invalidHelperUse
msg = printf( M2C( this.msgs.invalidHelperUse.msg ), ex.helper )
if ex.error
msg += '\n--> ' + assembleError.call( this, extend( true, {}, ex, {fluenterror: ex.error} )).msg;
#msg += printf( '\n--> ' + M2C( this.msgs.invalidParamCount.msg ), ex.expected );
quit = false
etype = 'warning'
when HMSTATUS.notOnPath
msg = printf( M2C(this.msgs.notOnPath.msg, 'bold'), ex.engine)
quit = false
etype = 'error'
when HMSTATUS.readError
if !ex.quiet
console.error(printf( M2C(this.msgs.readError.msg, 'red'), ex.file))
msg = ex.inner.toString()
etype = 'error'
when HMSTATUS.mixedMerge
msg = M2C this.msgs.mixedMerge.msg
quit = false
when HMSTATUS.invokeTemplate
msg = M2C this.msgs.invokeTemplate.msg, 'red'
msg += M2C( '\n' + WRAP(ex.inner.toString(), { width: 60, indent: ' ' }), 'gray' );
etype = 'custom'
when HMSTATUS.compileTemplate
etype = 'error'
when HMSTATUS.themeLoad
msg = M2C( printf( this.msgs.themeLoad.msg, ex.attempted.toUpperCase() ), 'red');
if ex.inner && ex.inner.fluenterror
msg += M2C('\nError: ', 'red') + assembleError.call( this, ex.inner ).msg
quit = true
etype = 'custom'
when HMSTATUS.parseError
if SyntaxErrorEx.is( ex.inner )
console.error printf( M2C(this.msgs.readError.msg, 'red'), ex.file )
se = new SyntaxErrorEx ex, ex.raw
msg = printf M2C( this.msgs.parseError.msg, 'red' ), se.line, se.col
else if ex.inner && ex.inner.line != undefined && ex.inner.col != undefined
msg = printf( M2C( this.msgs.parseError.msg, 'red' ), ex.inner.line, ex.inner.col)
else
msg = ex
etype = 'error'
msg: msg # The error message to display
withStack: withStack # Whether to include the stack
quit: quit
etype: etype