我目前正在探索可能的方法来处理AngularJS中的应用程序范围的异常。

我们真正想要避免的事情之一是在嵌套的try / catch块中包装应用程序的多个部分,但干净地处理事情 – 即响应promise而抛出异常。

>有没有人覆盖这个问题,并有任何建议?
>关于如何在服务以及控制器/指令中提取异常的任何建议。 (见下面 – 广播工作确定,但只有当你可以附加监听器到范围)。

进展到目前为止

几个短设计目标:

>允许来自应用程序的一部分的异常在其他地方 – 或者可能多个地方(即“向用户显示错误通知”,“禁用窗口小部件”)处理。
>提供常见错误状况的中央管理 – 即日志到服务器,向用户显示通知,重定向到登录。
>允许从控制器,指令和服务等抛出异常。
>最终允许本地化的消息。

我的团队目前的倾向是编写一个服务来处理异常,这将暴露一系列简单的调用:

exceptionService.warn('exception_token');

exceptionService.crit('another_exception_token');

这个服务然后格式化一个“异常”对象,并从rootscope广播。这将允许默认处理程序监视任何广播和应用默认操作,以及允许在其他范围中设置自定义侦听器,这可以处理更具体的条件,即禁用部分UI。

var exception = {
    token: 'exception_token',severity': 'crit'
};

// broadcast exception
$rootScope.$broadcast(
'application_exception',exception
);
我最近一直在想,并且它发生在我,当谈到一个良好的错误处理在JavaScript,它是不相关的哪个框架,你使用,Angular在别的东西。我最近为一个AngularJS项目写了一个这样的错误处理程序,但我做了一个方式,它可以在任何框架中使用。

这里是完整的代码。您可以直接使用它,或修改为您的需要…

/*
Factory errorFact is to simplify error handling and reporting in other objects.
It supports detailed error output as a text string and into the browser's console.

Usage example:

A function that supports return of an error object would have the following declaration
as its very first line:

var e = errorFact.create("objectName.funcName",arguments);
- in this declaration we specify the full object + method name as the first string parameter,- and as the second parameter we pass javascript's reserved variable called arguments,which
  provides reference to all of the function's parameters for logging.

When an error occurs,the function would return:

return e.error("Error description text");
 - this line will create and return a complete error context.

When a function that supports return of an error object makes a call into another
function that also supports the error context,then it can return the nested error
result by passing the embedded error to the current error object instead of the error
 text.

 Example:

 var e = errorFact.create("objectName.funcName",arguments);
 var data = callAnotherFunc(...); // calling a function that support an error object;
 if(data.isError){ // If an error was triggered;
    return e.error(data); // return that error from the current context;
 }

 The top-level code that calls an error-returning function would do verification
 and if an error occurred,log all its details into console (typically).

 Example:

 var data = getData(...);
 if(data.isError){
    data.log(); // Output all the error details into the browser's console;
 }
 */

"use strict";

app.factory("errorFact",function(){
    return {
        // creates a new error context;
        create: function(method,args){
            var result = {
                // initiates and returns the error context;
                error: function(msg){
                    this.info.isError = true;
                    if(msg.isError){
                        this.info.details.caller = msg;
                    }else{
                        this.info.details.msg = msg;
                    }
                    return this.info;
                },info:
                {
                    isError: false,details: {},log: function(){
                        if(this.isError){
                            console.error(this.format());
                        }
                    },// formats complete error details into a text string;
                    format: function(){
                        if(this.details.caller){
                            var txt = this.details.caller.format();
                            txt += "\nCALLER: " + this.details.method + "(" + this.formatArguments() + ")";
                            return txt;
                        }
                        if(this.details.method){
                            return "Error calling " + this.details.method + "(" + this.formatArguments() + "): " + this.details.msg;
                        }else{
                            return this.details.msg;
                        }
                        return "";
                    },// formats function argument details into a text string;
                    formatArguments: function(){
                        if(!this.details.args){
                            return "";
                        }
                        var params = "";
                        for(var i = 0;i < this.details.args.length;i ++){
                            if(params.length > 0){
                                params += ",";
                            }
                            var p = this.details.args[i];
                            if(p === undefined){
                                params += "undefined";
                            }else{
                                if(p === null){
                                    params += "null";
                                }else{
                                    if(typeof(p) == "object"){
                                        params += "Object";
                                    }else{
                                        params += p;
                                    }
                                }
                            }
                        }
                        return params;
                    }
                }
            };
            if(method){
                result.info.details.method = method;
            }
            if(args){
                result.info.details.args = args;
            }
            return result;
        }
    }
});

下面是一个显示如何使用它的工厂:

"use strict";

app.factory('moduleFact',['errorFact',function(errorFact){
    return {
        // Locates existing module and expands its key Id references
        // into corresponding object references:
        // - If 'hintGroupId' is present,property 'hints' is added from
        //   the corresponding hint group.
        // - If 'repModules' is present,properties 'question' and 'refs'
        //   are added.
        // On success,return the expanded module object.
        // On failure,returns an error object.
        //
        // NOTE: Currently supports only the first value in repModules.
        expandModule: function(moduleData,moduleId){
            var e = errorFact.create("moduleFact.expandModule",arguments);
            if(!moduleData || !moduleData.modules || !moduleId){
                return e.error("Invalid parameters passed");
            }
            var mod = this.findModule(moduleData,moduleId);
            if(mod.isError){
                return e.error(mod);
            }
            var src = mod;
            if(mod.repModules){
                var repId = mod.repModules[0];
                if(!repId){
                    return e.error("Invalid repModules encountered");
                }

                ///////////////////////////////////////
                // temporary check to throw a warning:
                if(mod.repModules.length > 1){
                    console.warn("Multiple values in property repModules: " + JSON.stringify(mod.repModules) +
                        ",which is not supported yet (only the first value is used)");
                }
                ///////////////////////////////////////

                src = this.findModule(moduleData,repId);
                if(src.isError){
                    return e.error(src);
                }
            }
            if(src.question){
                mod.question = src.question;
            }else{
                return e.error("Question not specified");
            }
            if(src.refs){
                mod.refs = src.refs;
            }
            if(src.hintGroupId){
                var hg = this.findHintGroup(moduleData,src.hintGroupId);
                if(hg.isError){
                    return e.error(hg);
                }
                mod.hints = hg.hints;
            }
            return mod; // needed extra: expand attribute repModules
        },// Expands all the modules and returns the data;
        expandAllModules: function(moduleData){
            var e = errorFact.create("moduleFact.expandAllModules",arguments);
            if(!moduleData || !moduleData.modules){
                return e.error("Invalid parameters passed");
            }
            for(var i = 0;i < moduleData.modules.length;i ++){
                var result = this.expandModule(moduleData,moduleData.modules[i].id);
                if(result.isError){
                    return e.error(result);
                }
            }
            return moduleData;
        },// Locates and returns module by its Id;
        findModule: function(moduleData,moduleId){
            var e = errorFact.create("moduleFact.findModule",arguments);
            if(!moduleData || !moduleData.modules || !moduleId){
                return e.error("Invalid parameters passed");
            }
            for(var i = 0;i < moduleData.modules.length;i ++){
                if(moduleData.modules[i].id == moduleId){
                    return moduleData.modules[i];
                }
            }
            return e.error("Module with Id = " + moduleId + " not found");
        },// Locates and returns Hint Group by its Id;
        findHintGroup: function(moduleData,hintGroupId){
            var e = errorFact.create("moduleFact.findHintGroup",arguments);
            if(!moduleData || !moduleData.hintGroups || !hintGroupId){
                return e.error("Invalid parameters passed");
            }
            for(var i = 0;i < moduleData.hintGroups.length;i ++){
                if(moduleData.hintGroups[i].id == hintGroupId){
                    return moduleData.hintGroups[i];
                }
            }
            return e.error("Hint Group with Id = " + hintGroupId + " not found");
        }
    }
}]);

所以,当你有这样的工厂,你的高级代码,如在控制器中只会记录任何问题,如下面的例子所示:

"use strict";

app.controller('standardsCtrl',['$scope','moduleFact',function($scope,moduleFact){

        var data = ...//getting data;
        var mod = moduleFact.expandAllModules(data);
        if(mod.isError){
            mod.log(); // log all error details into the console;
        }else{
            // use the data
        }
    });

}]);

异常处理 – 在AngularJS中应用程序异常处理的推荐做法的更多相关文章

  1. ios – 使用swift进行异常处理

    catch来处理它.如果故事板中没有视图控制器,则无法执行任何操作.这是程序员的错误,创建它的人应该处理这些问题.你不能因为这种错误而责怪iOS运行时.

  2. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  3. Swift41/90Days - 面向轨道编程 - Swift 中的异常处理

    问题在开发过程中,异常处理算是比较常见的问题了。我们把下面那根Failure的线路扩展一下,便会看到两条平行的线路,这便是“双轨模型”,这是用“面向轨道编程”思想解决异常处理的理论基础。这就是“面向轨道编程”。也就是说具体的业务只需要处理灰色部分的逻辑:“面向轨道”编程确实给我们提供了一个很有趣的思路。比如ValueTransformation.swift这个真实的完整案例,以及antitypical/Result这个封装完整的Result库。面向铁轨,春暖花开。

  4. 面向轨道编程 - Swift 中的异常处理

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. swift详解之十-------------异常处理、类型转换 ( Any and AnyObject )

    异常处理、类型转换注:本文为作者倾心整理,希望对大家有所帮助!在swift中,错误用复合ErrorType协议的值表示。swift处理异常和别的语言不同的是swift不会展开调用堆栈。在swift中throw语句的性能几乎和return一样通过try!所以上面的例子还能这么写结果是一模一样的Any和AnyObject的类型Swift为不确定类型提供了两种特殊类型别名:AnyObject可以代表任何class类型的实例。Any可以表示任何类型,包括方法类型。

  6. Swift2网络操作和异常处理

    相信写过Swift的人应该都知道Alamofire,它是AFNetworking的Swift版本,同一个作者写的。"的哲学,不过Swift一直很强调安全性,Apple显然也并不仅仅满足于让Swift困守iOS开发领域,加上早就公布了年底要开源,大家也很期待它作为一门通用编程语言在其他领域的作为。从各方面来看,Swift2.0增加了对异常处理的支持都在情理之中。在我看来异常处理最重要的用途有两点:写底层框架的时候可以抛出一些异常让框架的使用者去处理,这样框架会显得更加灵活。

  7. Swift 2.0 异常处理

    WWDC2015宣布了新的Swift2.0.这次重大更新给Swift提供了新的异常处理方法。在Swift中,guard有点像if但是他们有两个非常重要的区别guard必须强制有else语句只有在guard审查的条件成立,guard之后的代码才会运行。所以,使用catch你可以对异常的解析进行更为高级的处理7MyError.NotExist{//dealwithnotexistMyError.OutOfRange{//dealwithnotexist}这里值得提一下在Swift2.0中一个跟异常处理没有关系

  8. swift注意点

    如果我们想要像Objective-C里那样定义可选的接口方法,就需要将接口本身定义为Objective-C的,也即在protocol定义之前加上@objc。另外和Objective-C中的@optional不同,我们使用没有@符号的关键字optional来定义可选方法//swift中的错误处理,Objective-C没有原生的异常处理机制。后来通过添加NSException类,还有NS_DURING,NS_HANDLER和NS_ENDHANDLER宏才有了异常处理。这种方案现在被称为“经典的异常处理”,还

  9. Swift2.0-异常处理Exception handler

    Swift2.0-异常处理前言关于我们为什么要使用异常处理,请看百度百科为我们作出的描述,想要更详细的资料请点这里以上摘自百度百科:关联,在Objective-C中,异常处理一般都是使用NSError类接收异常和抛出异常,使用方法像这样不得不说,Swift的异常处理更为优雅,下面会重点介绍。去执行该函数不建议使用try!

  10. Swift try 异常处理机制

    不处理异常如果我不想处理异常怎么办,或者说,我非常确定某个方法或者函数虽然声明会抛出异常,但是我自己知道我在使用时候是绝对不会抛出任何异常的。当然,如果你使用try!,而你的方法或者函数抛出了异常,那么你会得到一个运行中异常所以我们开发者需要慎用哦。

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部