API Docs for: 0.2.2
Show:

File: src\R.Debug.js

module.exports = function(R) {
    var VError = require("verror");
    var _ = require("lodash");
    var assert = require("assert");
    var util = require("util");
    var Promise = require("bluebird");
    /**
     * <p>Debugging utilities embedded with R.<br />
     * Provides conditionals for dev/prod mode and associated assertions to avoid lengthy try/catch blocks in prod mode.</p>
     * @memberof R
     * @type {Object}
     * @class R.Debug
     */
    var Debug = /** @lends R.Debug */{
        /**
         * @method _mode
         * @return {String} string The basic string
         * @type {String}
         * @private
         */
        _mode: function() {
            /* If in node or envified browser environment, read from env */
            if(process && process.env && process.env.NODE_ENV) {
                return process.env.NODE_ENV;
            }
            /* Defaults to 'development'. */
            else {
                return 'development';
            }
        }(),
        /**
         * <p>Manually override mode to either 'production' or 'development'.<br/>
         * Use this if you don't want to use envify.</p>
         * @method setMode
         * @param {String} mode
         * @public
         */
        setMode: function setMode(mode) {
            assert('development' === mode || 'production' === mode, "R.Debug.setMode(...): mode should be either 'development' or 'production'.");
            R.Debug._mode = mode;
            if(process && process.env) {
                process.env.NODE_ENV = mode;
            }
            if(mode === 'production') {
                Debug.disableStackTracesForSetImmediate();
            }
        },
        _vanillaSetImmediate: null,
        _vanillaClearImmediate: null,
        enableStackTracesForSetImmediate: function enableStackTracesForSetImmediate() {
            assert(Debug.isDev(), "R.enableStackTracesForSetImmediate(...): should only be called in development mode.");
            assert(R._vanillaSetImmediate !== null, "R.enableStackTracesForSetImmediate(...): already enabled.");
            if(R.isClient()) {
                Debug._vanillaSetImmediate = window.setImmediate;
                Debug._vanillaClearImmediate = clearTimeout;
                window.setImmediate = _.defer;
                window.clearImmediate = clearTimeout;
            }
            else if(R.isServer()) {
                Debug._vanillaSetImmediate = global.setImmediate;
                Debug._vanillaClearImmediate = clearTimeout;
                global.setImmediate = _.defer;
                global.clearImmediate = clearTimeout;
            }
        },
        disableStackTracesForSetImmediate: function disableStackTracesForSetImmediate() {
            if(Debug._vanillaSetImmediate) {
                window.setImmediate = Debug._vanillaSetImmediate;
            }
            if(Debug._vanillaClearImmediate) {
                window.clearImmediate = Debug._vanillaClearImmediate;
            }
        },
        /**
         * <p> Returns a boolean describing whether the current mode is dev. </p>
         * @method isDev
         * @return {Boolean} boolean Truthy iff the current mode is dev.
         * @public
         */
        isDev: function isDev() {
            return 'development' === Debug._mode;
        },
        /**
         * <p> Returns a boolean describing whether the current mode is prod. </p>
         * @method isProd
         * @return {Boolean} boolean Truthy iff the current mode is prod.
         * @public
         */
        isProd: function isProd() {
            return 'production' === Debug._mode;
        },
        /**
         * <p>Runs a function iff the current mode is dev.</p>
         * @method dev
         * @param  {Function} fn The function to invoke iff the current mode is dev.
         * @return {*} * The return value of fn iff the current mode is dev, undefined otherwise.
         * @public
         */
        dev: function dev(fn) {
            return Debug.isDev() ? fn() : void 0;
        },
        /**
         * <p>Runs a function iff the current mode is prod.</p>
         * @method prod
         * @param  {Function} fn The function to invoke iff the current mode is prod.
         * @return {*} * The return value of fn iff the current mode is prod, undefined otherwise.
         * @public
         */
        prod: function prod(fn) {
            return Debug.isProd() ? fn(): void 0;
        },
        /**
         * <p>Returns a function iff the current mode is dev, otherwise returns a noop function.<br />
         * "dev-only" maybe monad.</p>
         * @method maybeDev
         * @param  {Function} fn The function to be returned if the current mode is dev.
         * @return {Function} The original function iff the current mode is dev, no-op function otherwise.
         * @public
         */
        maybeDev: function maybeDev(fn) {
            return Debug.isDev() ? fn : _.noop;
        },
        /**
         * <p>Returns a function iff the current mode is prod, otherwise returns a noop function.<br />
         * "prod-only" maybe monad.</p>
         * @method maybeProd
         * @param  {Function} fn The function to be returned if the current mode is prod.
         * @return {Function} The original function iff the current mode is prod, no-op function otherwise.
         * @public
         */
        maybeProd: function maybeProd(fn) {
            return Debug.isProd() ? fn : _.noop;
        },
        /**
         * <p>Trigger a debugger breakpoint without raising jshint errors.</p>
         * @method breakpoint
         * @public
         */
        breakpoint: function breakpoint() {
            /* jshint debug:true */
            debugger;
            /* jshint debug:false */
        },
        stackTrace: function stackTrace() {
            var err = new Error();
            return err.stack;
        },
        display: function display(name, obj) {
            console.warn("++++[ " + name + " ]++++");
            for(var k in obj) {
                console.warn(k, ":", obj[k]);
            }
            console.warn("----[ " + name + " ]----");
        },
        fail: function fail(err) {
            throw err;
        },
        /**
         * <p>Runs assert from node core with the same arguments.<br />
         * Throws if the assert fails and the current mode is dev.<br />
         * console.error if the assert fails and the current mode is prod.<br />
         * No side effect if the assert doesn't fail.</p>
         * @method check
         * @return {Boolean} Truthy only if the assert doesn't fail. False if the assert fails and not in dev mode.
         * @type {Function}
         * @public
         */
        check: function check() {
            try {
                assert.apply(null, arguments);
            }
            catch(err) {
                if(Debug.isDev()) {
                    Debug.fail(err);
                }
                else {
                    console.error(err);
                    return false;
                }
            }
            return true;
        },
        /**
         * <p>Extends an Error to provide additional information while preserving the error stack.<br />
         * Uses VError under the hood.</p>
         * @method extendError
         * @param  {Error} originalErr The original error.
         * @param  {Error|String} wrappingErr The error to use as wrapper.
         * @return {Error} The new, extended Error.
         * @public
         */
        extendError: function extendError(err, message) {
            err.message = message + ": " + err.message;
            return err;
        },
        /**
         * Returns a function that will rethrow when passed an error.
         * @method rethrow
         * @param  {Error|String} [wrappingErr] Optionnal error to use as wrapper.
         * @public
         */
        rethrow: function rethrow(message) {
            if(!message) {
                return function(err) {
                    if(err) {
                        Debug.fail(err);
                    }
                };
            }
            else {
                return function(err) {
                    if(err) {
                        console.error(message);
                        Debug.fail(err);
                    }
                };
            }
        },
    };

    if(Debug.isDev()) {
        Debug.enableStackTracesForSetImmediate();
        Promise.longStackTraces();
    }

    return Debug;
};