当前位置: 首页 > 知识库问答 >
问题:

如何使此异常处理代码符合DRY原则?

施赞
2023-03-14

我有一个特殊的情况,我需要捕获异常并将一个对象返回给客户端来代替异常。我不能将异常处理逻辑放在更高的级别,即将 Foo 包装在 try 子句中。

最好用一些样本代码来演示。异常处理逻辑模糊了方法的意图,如果我有,许多相似意图的方法,在Foo类中,我发现自己重复了大部分catch逻辑。

在下面的代码中包装常见异常功能的最佳技术是什么?

public class Foo
{
     public Bar SomeMethodThatCanThrowExcepetion()
     {
          try
          {
              return new Bar().Execute();
          }
          catch(BazException ex)
          {
              WriteLogMessage(ex, Bar.ErrorCode);
              return new Bar() { ErrorMessage = ex.Message, ErrorCode = Bar.ErrorCode;}                  
          }
     }

     public Baz SomeMethodThatCanThrowExcepetion(SomeObject stuff)
     {
          try
          {
              return new Baz(stuff).Execute();
          }
          catch(BazException ex)
          {
              WriteLogMessage(ex, Baz.ErrorCode);
              return new Baz() { ErrorMessage = ex.Message, ErrorCode = Baz.ErrorCode;}                  
          }
     }
 } 

共有3个答案

阮星火
2023-03-14

您真的需要在每个方法中显式记录吗?不要在每个方法中都有异常逻辑,而是在程序的< code>Main方法中有一个处理程序,并一般地处理异常。

另外,如果您真的需要日志记录,您不需要从catch块返回任意对象,只需使用< code > throw让它在堆栈中向上移动。

支嘉祥
2023-03-14

基类如何:

public class ErrorCapable {
  public string ErrorMessage { set; get; }
  public int ErrorCode { set; get; }

  public static ErrorCapable<T> Oops(Exception exc) where T : ErrorCapable, new() {
    // Code for logging error here
    return new T() { ErrorMessage = exc.Message, ErrorCode = exc.ErrorCode };
  }
}

public class Bar : ErrorCapable {
  //...
}
public class Baz : ErrorCapable {
  //...
}

然后在catch中,只需使用,例如:

return ErrorCapable.Oops<Bar>(ex);
葛昕
2023-03-14

根据Lee的评论更新

一种可能性是使用通用辅助方法。如下所示:

T TryExecute<T>(Func<T> action, int ErrorCode)
{
    try
    {
        return action();
    }
    catch (Exception ex)
    {
        result = Activator.CreateInstance<T>();
        typeof(T).GetProperty("ErrorMessage").SetValue(result, ex.Message, null);
        typeof(T).GetProperty("ErrorCode").SetValue(result, ErrorCode, null);
        return result;
    }
    return result;
}

如果你可以修改 Bar 和 Baz,那么你可以通过在 T 上放置一个要求来改进这一点:

public interface IError
{
    public string ErrorMessage { get; set; }
    public int ErrorCode { get; set; }
}

T TryExecute<T>(Func<T> action, int ErrorCode) where T : IError
{
    try
    {
        return action();
    }
    catch (Exception ex)
    {
        result = Activator.CreateInstance<T>();
        result.ErrorMessage = ex.Message;
        result.ErrorCode = ErrorCode;
        return result;
    }
}

然后你会用:

return TryExecute<Bar>(new Bar().Execute, Bar.ErrorCode);

和:

return TryExecute<Baz>(new Baz(stuff).Execute, Baz.ErrorCode);

对于您的特定设计来说,这可能是也可能不是过度抽象;魔鬼在细节中。

 类似资料:
  • 本文向大家介绍Java基础异常处理代码及原理解析,包括了Java基础异常处理代码及原理解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了java基础异常处理代码及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 异常的定义:中断了正常指令流的事件。 try..catch..finally结构: 输出结果: throw与thro

  • 本文向大家介绍C++常见异常处理原理及代码示例解析,包括了C++常见异常处理原理及代码示例解析的使用技巧和注意事项,需要的朋友参考一下 编程中常见的错误 程序的编译错误——比较好解决,主要是一些语法错误 程序的运行错误——产生因素较为复杂,如空间不够,下标越界,访问非法空间等。 异常是指程序运行时出现的不正常,可分为一下几类: CPU异常;如在计算过程中,出现除数为0的情况。 内存异常,如: 使用

  • 我有以下课程: SonarQube用变量标记所有三行上的错误: 移动此变量以符合Java规范约定。 如何使代码与SonarQube兼容? 我正在为Eclipse v2.6.0使用Sonarint。

  • 我已经将本文中的主要测试代码(此处是原始代码的链接)转换为处理。在测试它时,我发现它适用于低于10,000,000的数字,但它跳过了一些高于该数字的素数。 这是我的翻译(除了表格是相同的)。 编辑:我发现了问题。处理的int(long)转换为浮点数,然后转换为int,这会导致舍入错误。使用(int)long修复了问题。这是代码的工作(并且稍微优化)版本。 此版本仅适用于有符号整数。由于某种原因简单

  • 问题内容: 我们正在进行有关如何处理REST异常的持续讨论。 响应内容类型:JSON 我们有两种解决方案: 将所有未检查的异常作为JSON响应抛出。 发送请求无效响应代码。 参数: 当出现错误时,为什么要返回JSON?只需发送无效的响应码即可。 相反的观点: 对于普通开发人员而言,响应代码的技术性太强。 你怎么说? 问题答案: 对于JSON API,我最近开发了两者。我总是使用有效的JSON进行响

  • 问题内容: 这个问题已经在这里有了答案 : 我的PDO声明无效 (1个答案) 4年前关闭。 我正在尝试在php上使用类,但是在查找正确的错误处理方式时遇到了一些麻烦,我编写了以下代码: 这部分代码不报告错误,但根本不起作用,底部的var 返回空值。 有人可以帮我找到我错了吗? 问题答案: 除非您告知,否则PDO不会引发异常。你跑了吗: 在PDO对象上?