我可以组合try catch块吗?

时间:2011-12-15 02:45:33

标签: c#

我有以下代码:

    public IDictionary<string, string> GetNextBase36(string partitionKey, string rowKey, ref string seq)
    {
        Sequence sequence;
        try {
            sequence = _sequenceRepository.Get(u => u.PartitionKey == partitionKey & u.RowKey == rowKey);
        } catch {
            _errors.Add("", "Database error: Get sequence failed");
        }
        try {
            sequence.Value = Base36.Encode(Base36.Decode(sequence.Value) + 1);
            _sequenceRepository.AddOrUpdate(sequence);
            seq = sequence.Value;
        } catch {
            _errors.Add("", "Database error: Updating sequence failed");
        }
        return _errors;
    }

它可以工作,但是每个数据库访问都被try catch块包围似乎有点过分了。有什么方法可以简化这个吗?有没有更好的方法?

根据帮助/建议更新了代码:

    public IDictionary<string, string> GetNextBase36(string partitionKey, string rowKey, ref string seq)
    {
        Sequence sequence;
        string catchMsg = string.Empty;
        try {
            catchMsg = "Database error: Get sequence failed"
            sequence = _sequenceRepository.Get(u => u.PartitionKey == partitionKey & u.RowKey == rowKey);
            sequence.Value = Base36.Encode(Base36.Decode(sequence.Value) + 1);
            catchMsg = "Database error: Updating sequence failed"
            _sequenceRepository.AddOrUpdate(sequence);
            seq = sequence.Value;
        } catch {
            _errors.Add("", catchMsg);
        }
        return _errors;
    }

3 个答案:

答案 0 :(得分:4)

您正在牺牲错误消息可读性的祭坛上的确切异常堆栈跟踪(更不用说代码可读性)。

考虑您的受众:开发人员。开发人员应该能够读取异常堆栈跟踪,这是一个比短错误消息更有价值的调试信息。

因此我的建议是只放入一个异常处理程序,以便在层次结构的更高位置进行记录。如果您必须在当前方法中使用一个,至少捕获完整的异常堆栈跟踪。

此外 - 在第一个例外之后继续是否真的有意义?如果检索序列失败,则在下一个try块中使用它的值将不再公平。这里有多个try / catch块是没有意义的,除非你确切知道如何在每个catch处理程序中解决问题,以便继续。

更新

现在您只有一个try / catch块代码可读性得到改进。你基本上把一个错误列表返回给调用者看起来仍然很奇怪 - 错误情况应该是例外的,所以它不应该渗透到你的方法的业务逻辑中,而是我只是让异常进入堆栈直到你可以真正处理问题(或者只是记录它并退出应用程序)。

答案 1 :(得分:2)

理想情况下你的代码应该是这样的(我将在这里和那里发明类名):即你应该有一个try块和多个处理程序,这取决于引发的异常类型。

你应该只有一个try块的原因是,正如其他人指出的那样,两个查询是相关的,如果select出错了你不应该执行更新。

public IDictionary<string, string> GetNextBase36(string partitionKey, string rowKey, ref string seq)
{
    Sequence sequence;
    try {
        sequence = _sequenceRepository.Get(u => u.PartitionKey == partitionKey & u.RowKey == rowKey);
        sequence.Value = Base36.Encode(Base36.Decode(sequence.Value) + 1);
        _sequenceRepository.AddOrUpdate(sequence);
        seq = sequence.Value;
    } catch( SelectException e )  {
        _errors.Add("", "Database error:  Get sequence failed");
    } catch( UpdateException e )  {
        _errors.Add("", "Database error: Updating sequence failed");
    } catch {
        _errors.Add("", "Database error: Something really bad happened!");
    }

    return _errors;
}

答案 2 :(得分:1)

如果您无法从数据库中获取该项,那么您是否应该尝试更新它?如果打算处理/翻译代码中 点的异常,请将整个内容包装在一个try { ... } catch ()中。