<commit_before>var xhr       = require('xhr')
var shoe      = require('shoe')('/smokestack')
var slice     = require('sliced')
var isDom     = require('is-dom')
var format    = require('util').format
var convert   = require('convert-source-map')
var console   = window.console
var SourceMap = require('source-map').SourceMapConsumer

// magical auto-correction of error stack traces in v8
require('source-map-support').install()

// keep around so can call
// console methods without sending data to server
var nativeConsole = {}

;['error'
, 'info'
, 'log'
, 'debug'
, 'warn'
].forEach(function(k) {
  var nativeMethod = console[k]
  nativeConsole[k] = nativeMethod.bind(console)
  var prefix = k

  console[k] = function() {
    // keep original args so browser can log as usual
    var args = slice(arguments)
    write(prefix, args)
    return nativeMethod.apply(this, args)
  }
})

function write(prefix, args) {
  // prepare args for transport
  var cleanArgs = args.map(function(item) {
    // no sensible default for stringifying
    // DOM Elements nicely so just toString and let
    // whoever is logging handle stringification.
    if (item && isDom(item)) return item.toString()
    return item
  })

  var output = format.apply(null, cleanArgs)
  var data = JSON.stringify([prefix].concat(output))

  shoe.write(data)
  shoe.write('\n')
}

var close = window.close

window.close = function() {
  setTimeout(function() {
    shoe.write(JSON.stringify({ end: true }))
    shoe.write('\n')
    shoe.once('data', function() {
      shoe.end()
    })
  })
}

shoe.on('end', function() {
  close()
})

xhr('script.js', function(err, resp) {
  if (err) return console.error(err)
  var src = resp.body
  var sourceMap = convert.fromSource(src)
  // Not all browsers support the full function signature
  // of window.onerror, so the Error instance is not always
  // guaranteed:
  // http://danlimerick.wordpress.com/2014/01/18/how-to-catch-javascript-errors-with-window-onerror-even-on-chrome-and-firefox/
  window.onerror = function(message, filename, line, col, error) {
    var supportsError = !!error
    if (!supportsError) {
      var error = new Error(message)
      error.stack = 'Error: '+message+'\n    at '+filename+':'+line+':'+col
    }
    error.fileName = error.fileName || filename
    error.lineNumber = error.lineNumber || line
    error.columnNumber = error.columnNumber || col
    if (supportsError && sourceMap) {
      var sm = sourceMap.toObject()
      var smc = new SourceMap(sm)
      var original = smc.originalPositionFor({line: error.lineNumber, column: error.columnNumber})
      var source = smc.sourceContentFor(original.source)
      logError(source, error, original)
    } else {
      logError(src, error)
    }
    window.close()
  }

  var script = document.createElement("script")
  script.type = "text\/javascript"
  document.body.appendChild(script)
  script.src = 'script.js'
})

function logError(src, error, position) {
  var lines = src.trim().split('\n')
  position = position || {
    line: error.lineNumber,
    column: error.columnNumber,
    source: error.filename
  }
  var errorLine = '' + lines[position.line - 1]
  var spaces = ''
  write('error', [position.source + ':' +position.line])
  for (var i = 0; i < position.column; i++) {
    spaces += ' '
  }
  var columnLine = spaces + '^'
  var errorLines = [errorLine, columnLine]
  // write different data to remote console
  // and window console.
  write('error', [errorLines.join('\n') + '\n'])
  write('error', [error.stack])
  nativeConsole.error(error)
}
<commit_msg>Deal with callstack get errors<commit_after>var xhr       = require('xhr')
var shoe      = require('shoe')('/smokestack')
var slice     = require('sliced')
var isDom     = require('is-dom')
var format    = require('util').format
var convert   = require('convert-source-map')
var console   = window.console
var SourceMap = require('source-map').SourceMapConsumer

// magical auto-correction of error stack traces in v8
require('source-map-support').install()

// keep around so can call
// console methods without sending data to server
var nativeConsole = {}

;['error'
, 'info'
, 'log'
, 'debug'
, 'warn'
].forEach(function(k) {
  var nativeMethod = console[k]
  nativeConsole[k] = nativeMethod.bind(console)
  var prefix = k

  console[k] = function() {
    // keep original args so browser can log as usual
    var args = slice(arguments)
    write(prefix, args)
    return nativeMethod.apply(this, args)
  }
})

function write(prefix, args) {
  // prepare args for transport
  var cleanArgs = args.map(function(item) {
    // no sensible default for stringifying
    // DOM Elements nicely so just toString and let
    // whoever is logging handle stringification.
    if (item && isDom(item)) return item.toString()
    return item
  })

  var output = format.apply(null, cleanArgs)
  var data = JSON.stringify([prefix].concat(output))

  shoe.write(data)
  shoe.write('\n')
}

var close = window.close

window.close = function() {
  setTimeout(function() {
    shoe.write(JSON.stringify({ end: true }))
    shoe.write('\n')
    shoe.once('data', function() {
      shoe.end()
    })
  })
}

shoe.on('end', function() {
  close()
})

xhr('script.js', function(err, resp) {
  if (err) return console.error(err)
  var src = resp.body
  var sourceMap = convert.fromSource(src)
  // Not all browsers support the full function signature
  // of window.onerror, so the Error instance is not always
  // guaranteed:
  // http://danlimerick.wordpress.com/2014/01/18/how-to-catch-javascript-errors-with-window-onerror-even-on-chrome-and-firefox/
  window.onerror = function(message, filename, line, col, error) {
    var supportsError = !!error
    if (!supportsError) {
      var error = new Error(message)
      error.stack = 'Error: '+message+'\n    at '+filename+':'+line+':'+col
    }
    error.fileName = error.fileName || filename
    error.lineNumber = error.lineNumber || line
    error.columnNumber = error.columnNumber || col
    if (supportsError && sourceMap) {
      var sm = sourceMap.toObject()
      var smc = new SourceMap(sm)
      var original = smc.originalPositionFor({line: error.lineNumber, column: error.columnNumber})
      var source = smc.sourceContentFor(original.source)
      logError(source, error, original)
    } else {
      logError(src, error)
    }
    window.close()
  }

  var script = document.createElement("script")
  script.type = "text\/javascript"
  document.body.appendChild(script)
  script.src = 'script.js'
})

function logError(src, error, position) {
  var lines = src.trim().split('\n')
  position = position || {
    line: error.lineNumber,
    column: error.columnNumber,
    source: error.filename
  }
  var errorLine = '' + lines[position.line - 1]
  var spaces = ''
  write('error', [position.source + ':' +position.line])
  for (var i = 0; i < position.column; i++) {
    spaces += ' '
  }
  var columnLine = spaces + '^'
  var errorLines = [errorLine, columnLine]
  // write different data to remote console
  // and window console.
  write('error', [errorLines.join('\n') + '\n'])
  
  // it's possible that we can fail to get a stack
  try {
    write('error', [error.stack])
  }
  catch (e) {
    write('error', ['Could not get stack trace because:', e.message])
  }

  nativeConsole.error(error)
}

{'fraction_non_alphanumeric': 0.14342141105965678, 'fraction_numerical': 0.0029964587305911197, 'mean_word_length': 3.334710743801653, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1144676', 'n_tokens_mistral': 2305, 'n_tokens_neox': 2298, 'n_words': 603}