<commit_before>
/**
 * Module dependencies.
 */

var debug = require('debug')('koa:app');
var Emitter = require('events').EventEmitter;
var compose = require('koa-compose');
var context = require('./context');
var Cookies = require('cookies');
var Stream = require('stream');
var http = require('http');
var co = require('co');

/**
 * Application prototype.
 */

var app = Application.prototype;

/**
 * Expose `Application`.
 */

exports = module.exports = Application;

/**
 * Initialize a new `Application`.
 *
 * @api public
 */

function Application() {
  if (!(this instanceof Application)) return new Application;
  this.env = process.env.NODE_ENV || 'development';
  this.outputErrors = 'test' != this.env;
  this.subdomainOffset = 2;
  this.poweredBy = true;
  this.jsonSpaces = 2;
  this.middleware = [];
  this.Context = createContext(); 
  this.context(context);
}

/**
 * Inherit from `Emitter.prototype`.
 */

Application.prototype.__proto__ = Emitter.prototype;

/**
 * Shorthand for:
 *
 *    http.createServer(app.callback()).listen(...)
 *
 * @param {Mixed} ...
 * @return {Server}
 * @api public
 */

app.listen = function(){
  var server = http.createServer(this.callback());
  return server.listen.apply(server, arguments);
};

/**
 * Use the given middleware `fn`.
 *
 * @param {Function} fn
 * @return {Application} self
 * @api public
 */

app.use = function(fn){
  debug('use %s', fn.name || 'unnamed');
  this.middleware.push(fn);
  return this;
};

/**
 * Mixin `obj` to this app's context.
 *
 *   app.context({
 *     get something(){
 *       return 'hi';
 *     },
 *
 *     set something(val){
 *       this._something = val;
 *     },
 *
 *     render: function(){
 *       this.body = '<html></html>';
 *     }
 *   });
 *
 * @param {Object} obj
 * @return {Application} self
 * @api public
 */

app.context = function(obj){
  var ctx = this.Context.prototype;
  Object.getOwnPropertyNames(obj).forEach(function(name){
    var descriptor = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(ctx, name, descriptor);
  });
  return this;
};

/**
 * Return a request handler callback
 * for node's native htto server.
 *
 * @return {Function}
 * @api public
 */

app.callback = function(){
  var mw = [respond].concat(this.middleware);
  var fn = compose(mw)(downstream);
  var onerror = this.onerror.bind(this);
  var self = this;

  return function(req, res){
    var ctx = new self.Context(self, req, res);

    if (!ctx.socket.listeners('error').length) {
      ctx.socket.on('error', onerror);
    }

    function done(err) {
      if (err) ctx.onerror(err);
    }

    co.call(ctx, function *(){
      yield fn;
    }, done);
  }
};

/**
 * Default error handler.
 *
 * @param {Error} err
 * @api private<commit_msg>add app.error(fn). Closes #4<commit_after>
/**
 * Module dependencies.
 */

var debug = require('debug')('koa:app');
var Emitter = require('events').EventEmitter;
var compose = require('koa-compose');
var context = require('./context');
var Cookies = require('cookies');
var Stream = require('stream');
var http = require('http');
var co = require('co');

/**
 * Application prototype.
 */

var app = Application.prototype;

/**
 * Expose `Application`.
 */

exports = module.exports = Application;

/**
 * Initialize a new `Application`.
 *
 * @api public
 */

function Application() {
  if (!(this instanceof Application)) return new Application;
  this.env = process.env.NODE_ENV || 'development';
  this.outputErrors = 'test' != this.env;
  this.subdomainOffset = 2;
  this.poweredBy = true;
  this.jsonSpaces = 2;
  this.middleware = [];
  this.Context = createContext(); 
  this.context(context);
}

/**
 * Inherit from `Emitter.prototype`.
 */

Application.prototype.__proto__ = Emitter.prototype;

/**
 * Shorthand for:
 *
 *    http.createServer(app.callback()).listen(...)
 *
 * @param {Mixed} ...
 * @return {Server}
 * @api public
 */

app.listen = function(){
  var server = http.createServer(this.callback());
  return server.listen.apply(server, arguments);
};

/**
 * Use the given middleware `fn`.
 *
 * @param {Function} fn
 * @return {Application} self
 * @api public
 */

app.use = function(fn){
  debug('use %s', fn.name || 'unnamed');
  this.middleware.push(fn);
  return this;
};

/**
 * Mixin `obj` to this app's context.
 *
 *   app.context({
 *     get something(){
 *       return 'hi';
 *     },
 *
 *     set something(val){
 *       this._something = val;
 *     },
 *
 *     render: function(){
 *       this.body = '<html></html>';
 *     }
 *   });
 *
 * @param {Object} obj
 * @return {Application} self
 * @api public
 */

app.context = function(obj){
  var ctx = this.Context.prototype;
  Object.getOwnPropertyNames(obj).forEach(function(name){
    var descriptor = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(ctx, name, descriptor);
  });
  return this;
};

/**
 * Return a request handler callback
 * for node's native htto server.
 *
 * @return {Function}
 * @api public
 */

app.callback = function(){
  var mw = [respond].concat(this.middleware);
  var fn = compose(mw)(downstream);
  var onerror = this.onerror.bind(this);
  var self = this;

  return function(req, res){
    var ctx = new self.Context(self, req, res);

    if (!ctx.socket.listeners('error').length) {
      ctx.socket.on('error', onerror);
    }

    function done(err) {
      if (err) ctx.onerror(err);
    }

    co.call(ctx, function *(){
      yield fn;
    }, done);
  }
};

/**
 * Set the application-level error handling `fn`.
 *
 * @param {Function} fn
 * @api public
 */

app.error = function(fn){
  this.onerror = fn;
};

/**
 * Default error handler.
 *
 * @param {Error} err
 * @api private
{'fraction_non_alphanumeric': 0.17573954139681427, 'fraction_numerical': 0.000875196919306844, 'mean_word_length': 3.2169741697416976, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '2179477', 'n_tokens_mistral': 1864, 'n_tokens_neox': 1841, 'n_words': 443}