// Load modules

var Http = require('http');
var NodeUtil = require('util');
var Utils = require('./utils');


// Declare internals

var internals = {};


exports = module.exports = internals.Error = function (code, message, options) {

    Utils.assert(this.constructor === internals.Error, 'Error must be instantiated using new');
    Utils.assert(!options || !options.toResponse || typeof options.toResponse === 'function', 'options.toReponse must be a function');
    Utils.assert(code >= 400 && code < 600, 'Error code must be 4xx or 5xx');

    Error.call(this);

    this.name = 'HapiError';
    this.code = code;
    this.message = message;
    this.settings = Utils.clone(options) || {};               // Options can be reused;

    return this;
};

NodeUtil.inherits(internals.Error, Error);


internals.Error.prototype.toResponse = function () {

    if (this.settings.toResponse) {

        return this.settings.toResponse.call(this);
    }

    var response = {
        code: this.code,
        payload: {
            error: Http.STATUS_CODES[this.code] || 'Unknown',
            code: this.code,
            message: this.message
        }
        // contentType: 'application/json'
    };

    for (var d in this) {
        if (this.hasOwnProperty(d) &&
            !response.payload.hasOwnProperty(d)) {

            response.payload[d] = this[d];
        }
    }

    return response;
};


// Utilities

internals.Error.badRequest = function (message) {

    return new internals.Error(400, message);
};


internals.Error.unauthorized = function (message) {

    return new internals.Error(401, message);
};


internals.Error.forbidden = function (message) {

    return new internals.Error(403, message);
};


internals.Error.notFound = function (message) {

    return new internals.Error(404, message);
};


internals.Error.internal = function (message, data) {

    var format = function () {

        var response = {
            code: 500,
            payload: {
                error: Http.STATUS_CODES[500],
                code: 500,
                message: 'An internal server error occurred'                // Hide actual error from user
            }
        };

        return response;
    };

    var err = new internals.Error(500, message, { toResponse: format });
    err.trace = Utils.callStack(1);
    err.data = data;
    return err;
};


internals.Error.passThrough = function (code, payload, contentType) {

    var format = function () {

        var response = {
            code: code,
            payload: payload,
            contentType: contentType
        };

        return response;
    };

    var err = new internals.Error(code, 'Pass-through', { toResponse: format });
    return err;
};


internals.Error.toResponse = function (err) {

    Utils.assert(err instanceof Error, 'Input must be instance of Error');

    if (err instanceof internals.Error) {

        return err.toResponse();
    }

    // Other Error

    var response = {
        code: 500,
        payload: {
            message: err.message,
            name: err.name
        }
    };

    for (var d in err) {
        if (err.hasOwnProperty(d)) {
            response.payload[d] = err[d];
        }
    }

    return response;
};







@@ -2668,20 +2668,19 @@
 s.Error(
-code
+500
 , 'Pass-
@@ -2709,24 +2709,209 @@
 : format %7D);
+     // 500 code is only used internally and is not exposed when sent%0A%0A    err.passThrough = %7B%0A        code: code,%0A        payload: payload,%0A        contentType: contentType%0A    %7D;%0A    
 %0A    return 

Allow non 4xx 5xx codes in pass-through errors