gpt4 book ai didi

c# - 当这么多事情都可能出错时,你所做的就是尝试,尝试,尝试

转载 作者:可可西里 更新时间:2023-11-01 08:34:24 28 4
gpt4 key购买 nike

说真的,你怎么能在不发疯的情况下处理所有这些异常呢?我是不是读了太多关于异常处理的文章或什么?我尝试重构了几次,但每次似乎都以更糟糕的结果告终。也许我应该承认确实会发生异常(exception)情况,并且只是享受编写代码的快乐之路? ;) 那么这段代码有什么问题(除了我懒得只是抛出 Exception 而不是更具体的东西这一事实之外)?无论如何,不​​要对我好过。

public void Export(Database dstDb)
{
try
{
using (DbConnection connection = dstDb.CreateConnection())
{
connection.Open();
DbTransaction transaction = connection.BeginTransaction();
try
{
// Export all data here (insert into dstDb)
transaction.Commit();
}
catch (SqlException sqlex)
{
ExceptionHelper.LogException(sqlex);
try
{
transaction.Rollback();
}
catch (Exception rollbackEx)
{
logger.Error("An exception of type " + rollbackEx.GetType() +
" was encountered while attempting to roll back the transaction.");
}
throw new Exception("Error exporting message " + Type + " #" + Id + ": [" + sqlex.GetType() + "] " + sqlex.Message, sqlex);
}
catch (Exception ex)
{
try
{
transaction.Rollback();
}
catch (Exception rollbackEx)
{
logger.Error("An exception of type " + rollbackEx.GetType() +
" was encountered while attempting to roll back the transaction.");
}
throw new Exception("Error exporting message " + Type + " #" + Id + ": [" + ex.GetType() + "] " + ex.Message, ex);
}
}

try
{
Status = MessageStatus.FINISHED;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
logger.ErrorException("Failed to change message status to FINISHED: " +
Type + " #" + Id + ": " + statusEx.Message, statusEx);
}
}
catch (Exception importEx)
{
try
{
Status = MessageStatus.ERROR;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
logger.ErrorException("Failed to change message status to ERROR: " +
Type + " #" + Id + ": " + statusEx.Message, statusEx);
}
AddErrorDescription(importEx.Message);
throw new Exception("Couldn't export message " + Type + " #" + Id + ", exception: " + importEx.Message, importEx);
}
}

顺便说一句。很多次,我真的很努力地在形成问题时尽可能具体 - 结果是没有访问,没有答案,也不知道如何解决问题。这一次我一直在想当别人的问题引起我的注意时,我猜这是正确的做法:)

更新:

我已经尝试将一些技巧付诸实践,以下是我到目前为止的想法。我决定稍微改变一下行为:当成功导出后无法将消息状态设置为 FINISHED 时,我认为它是未完全完成的工作,我回滚并抛出异常。如果你们还有一些耐心,请让我知道它是否更好。或者提出更多批评。顺便提一句。感谢所有的回答,我分析了每一个。

抛出 System.Exception 的实例感觉不对,所以我按照建议放弃了它,而是决定引入自定义异常。顺便说一句,这似乎也不对 - 矫枉过正?这对于公共(public)方法似乎没问题,但对于私有(private)成员来说有点过度设计,但我仍然想知道更改消息状态而不是数据库连接或其他问题存在问题。

我可以在这里看到几种提取方法的方法,但它们似乎都混合了职责 jgauffinhis comment 中提到:管理数据库连接,处理数据库操作,业务逻辑(导出数据)。比如说 ChangeStatus 方法——它是某种抽象级别——你改变了消息的状态,你对这件事是如何发生的、消息是如何持久化的等不感兴趣。也许我应该使用Data Mapper 模式进一步分离职责,但在这个仍然非常简单的场景中,我认为我会摆脱 Active Record。也许现在整个设计太复杂了,我不知道该从哪里切入?

public void Export(Database dstDb)
{
try
{
using (DbConnection connection = dstDb.CreateConnection())
{
connection.Open();
using (DbTransaction transaction = connection.BeginTransaction())
{
// Export all data here (insert into dstDb)
ChangeStatus(MessageStatus.FINISHED);
transaction.Commit();
}
}
}
catch (Exception exportEx)
{
try
{
ChangeStatus(MessageStatus.ERROR);
AddErrorDescription(exportEx.Message);
}
catch (Exception statusEx)
{
throw new MessageException("Couldn't export message and set its status to ERROR: " +
exportExt.Message + "; " + statusEx.Message, Type, Id, statusEx);
}
throw new MessageException("Couldn't export message, exception: " + exportEx.Message, Type, Id, exportEx);
}
}

private void ChangeStatus(MessageStatus status)
{
try
{
Status = status;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
throw new MessageException("Failed to change message status to " + status + ":" + statusEx.Message, statusEx);
}
}

最佳答案

  1. 数据集是万恶之源 ;) 尝试改用 ORM。
  2. 了解 single responsibility principle .你的代码做了很多不同的事情。
  3. 不要捕获异常然后重新抛出它们
  4. 在事务和连接上使用using 语句。
  5. 当所有异常处理程序都做同样的事情时,不需要捕获所有不同的异常。异常详细信息(异常类型和消息属性)将提供信息。

关于c# - 当这么多事情都可能出错时,你所做的就是尝试,尝试,尝试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3148512/

28 4 0
文章推荐: mysql - 与 MYSQL 的新 innodb memcached 插件混淆?
文章推荐: c# - 确定 .NET 中两个 IEnumerable 集的相对补码
文章推荐: php - 无法通过 POST 方法将