Skip to content

Angular打印错误的minErr函数 #18

Closed
@Wscats

Description

@Wscats
Owner

angular minErr函数的源码是这样的,这个函数主要用来输出错误的提示信息

function minErr(module) {
    return function() {
        var message, i, code = arguments[0],
            prefix = "[" + (module ? module + ":" : "") + code + "] ",
            template = arguments[1],
            templateArgs = arguments,
            stringify = function(obj) {
                return "function" == typeof obj ? obj.toString().replace(/ \{[\s\S]*$/, "") : "undefined" == typeof obj ? "undefined" : "string" != typeof obj ? JSON.stringify(obj) : obj
            };
        for (message = prefix + template.replace(/\{\d+\}/g, function(match) {
                var arg, index = +match.slice(1, -1);
                return index + 2 < templateArgs.length ? (arg = templateArgs[index + 2], "function" == typeof arg ? arg.toString().replace(/ ?\{[\s\S]*$/, "") : "undefined" == typeof arg ? "undefined" : "string" != typeof arg ? toJson(arg) : arg) : match
            }), message = message + "\nhttp://errors.angularjs.org/1.2.1/" + (module ? module + "/" : "") + code, i = 2; i < arguments.length; i++) message = message + (2 == i ? "?" : "&") + "p" + (i - 2) + "=" + encodeURIComponent(stringify(arguments[i]));
        return new Error(message)
    }
}

从这个函数中可以学到几点东西
首先是里面这个正则
template.replace(/\{\d+\}/g)
这个正则是匹配所有"{1个或更多数字}"形式的字符串
例如

var a = "{1}233{2}";
message = a.replace(/(\{)(\d+)(\})/g, 'wscats');//加了括号方便理解

相当于
new RegExp("\{\d+\}", "g")//g代表 global match(全定匹配)

其次是return new Error(message),这个

ngMinErr = minErr("ng");
throw ngMinErr("badname","hasOwnProperty is not a valid {0} name","module");

抛出打印的异常

function checkInput(x) {
    try {
        if (isNaN(parseInt(x))) {
            throw new Error("Input is not a number.");
        }
    } catch (e) {
        document.write(e.description);
        console.log(new Error("Input is not a number."));
    }
}
checkInput("not a number");

输出如下的异常信息
Uncaught Error: [ng:badname] hasOwnProperty is not a valid module name
http://errors.angularjs.org/1.2.1/ng/badname?p0=module"

这里如果throw new Error("wscats");之后,后面的代码就会得不到执行

Activity

Wscats

Wscats commented on May 20, 2016

@Wscats
OwnerAuthor

无意之中看到了一篇文章
http://my.oschina.net/myprogworld/blog/207692

在1.2.5的版本中这里的第一个函数是这样写的

function minErr(module) {
  return function () {
    var code = arguments[0],
      prefix = '[' + (module ? module + ':' : '') + code + '] ',
      template = arguments[1],
      templateArgs = arguments,
      stringify = function (obj) {
        if (typeof obj === 'function') {
          return obj.toString().replace(/ \{[\s\S]*$/, '');
        } else if (typeof obj === 'undefined') {
          return 'undefined';
        } else if (typeof obj !== 'string') {
          return JSON.stringify(obj);
        }
        return obj;
      },
      message, i;

    message = prefix + template.replace(/\{\d+\}/g, function (match) {
      var index = +match.slice(1, -1), arg;

      if (index + 2 < templateArgs.length) {
        arg = templateArgs[index + 2];
        if (typeof arg === 'function') {
          return arg.toString().replace(/ ?\{[\s\S]*$/, '');
        } else if (typeof arg === 'undefined') {
          return 'undefined';
        } else if (typeof arg !== 'string') {
          return toJson(arg);
        }
        return arg;
      }
      return match;
    });

    message = message + '\nhttp://errors.angularjs.org/1.2.5/' +
      (module ? module + '/' : '') + code;
    for (i = 2; i < arguments.length; i++) {
      message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
        encodeURIComponent(stringify(arguments[i]));
    }

    return new Error(message);
  };
}

其实区别只是在于把message = prefix + template.replace(/{\d+}/g...这段放在for里面而已,其实我是喜欢1.2.5这一段代码的写法,因为比较清晰明了

而后面angular调用这个方法会根据传的是两个参数还是三个参数进行打印
例如这样
throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", tag)
这里面的{0}就会被代码中的正则处理了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Wscats

        Issue actions

          Angular打印错误的minErr函数 · Issue #18 · Wscats/articles