code: function onError (data) {
      var map = sourceMap.map()
      var error
      var smc
  
      if (!data.length) {
        return
      }
  
      // if what we get isn't json, it's some other undescribed phantom error;
      // just echo it.
      try {
        error = JSON.parse(data.toString())
      } catch (e) {
        io.stderr.write(sprintf('\n\n%s\n', data.toString()))
  
        return
      }
  
      // if a source map wasn't present, just output the line numbers where an
      // error occurred
      if (!map) {
        io.stderr.write(sprintf('\n\n%s\n', error.message))
  
        if (error.trace && error.trace.length) {
          error.trace.forEach(function (e) {
            io.stderr.write(sprintf('    at :%d', e.line))
  
            if (e.function) {
              io.stderr.write(sprintf(' (in function %s)', e.function))
            }
  
            io.stderr.write('\n')
          })
        }
  
        return
      }
  
      // else, make sense of the sourcemap and output that information
      smc = new Consumer(map)
  
      io.stderr.write(sprintf('\n\n%s\n', error.message))
  
      if (error.trace && error.trace.length) {
        error.trace.forEach(function (e) {
          if (!e.line) {
            return
          }
  
          // phantom doesn't provide columns in stack traces
          var err = smc.originalPositionFor(
              {line: e.line, column: e.column || 0}
          )
  
          io.stderr.write(sprintf('    at %s:%d\n', err.source, err.line))
        })
      }
    }
docs: TODO: this section requires significant cleanup phantomjs has some interesting challenges, in that we can only communicate sourcemaps were an after-thought, and the API needs redesign to support them correctly, and be less fragile