all files / liquidjs/src/util/ error.js

100% Statements 61/61
100% Branches 14/14
100% Functions 10/10
100% Lines 61/61
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107   81× 81× 80×       50×   50× 50× 50×   50× 50× 50×         26× 26×   26×       20×   17× 17×   17×         24× 24×     50× 50× 50×   50×   104×               50×     104× 104× 104× 104×     50× 50×   50× 49×   50×                  
const _ = require('./underscore.js')
 
function initError () {
  this.name = this.constructor.name
  if (Error.captureStackTrace) {
    Error.captureStackTrace(this, this.constructor)
  }
}
 
function initLiquidError (message, token) {
  initError.call(this)
 
  this.input = token.input
  this.line = token.line
  this.file = token.file
 
  var context = mkContext(token.input, token.line)
  this.message = mkMessage(message, token)
  this.stack = context + '\n' + (this.stack || this.message)
}
 
function TokenizationError (message, token) {
  initLiquidError.call(this, message, token)
}
TokenizationError.prototype = Object.create(Error.prototype)
TokenizationError.prototype.constructor = TokenizationError
 
function ParseError (e, token) {
  _.assign(this, e)
  this.originalError = e
 
  initLiquidError.call(this, e.message, token)
}
ParseError.prototype = Object.create(Error.prototype)
ParseError.prototype.constructor = ParseError
 
function RenderError (e, tpl) {
  // return the original render error
  if (e instanceof RenderError) {
    return e
  }
  _.assign(this, e)
  this.originalError = e
 
  initLiquidError.call(this, e.message, tpl.token)
}
RenderError.prototype = Object.create(Error.prototype)
RenderError.prototype.constructor = RenderError
 
function RenderBreakError (message) {
  initError.call(this)
  this.message = message + ''
}
RenderBreakError.prototype = Object.create(Error.prototype)
RenderBreakError.prototype.constructor = RenderBreakError
 
function AssertionError (message) {
  initError.call(this)
  this.message = message + ''
}
AssertionError.prototype = Object.create(Error.prototype)
AssertionError.prototype.constructor = AssertionError
 
function mkContext (input, line) {
  var lines = input.split('\n')
  var begin = Math.max(line - 2, 1)
  var end = Math.min(line + 3, lines.length)
 
  var context = _
    .range(begin, end + 1)
    .map(l => [
      (l === line) ? '>> ' : '   ',
      align(l, end),
      '| ',
      lines[l - 1]
    ].join(''))
    .join('\n')
 
  return context
}
 
function align (n, max) {
  var length = (max + '').length
  var str = n + ''
  var blank = Array(length - str.length).join(' ')
  return blank + str
}
 
function mkMessage (msg, token) {
  msg = msg || ''
  if (token.file) {
    msg += ', file:' + token.file
  }
  if (token.line) {
    msg += ', line:' + token.line
  }
  return msg
}
 
module.exports = {
  TokenizationError,
  ParseError,
  RenderBreakError,
  AssertionError,
  RenderError
}