这是捕获和处理异常/错误的有效方法吗?

时间:2011-12-24 03:12:35

标签: c# exception exception-handling

我现在使用以下代码来捕获错误并在我的服务层中抛出异常:

 ...
            if (pk == null || rk == null) return null;
            try
            {
                var item = repo.GetPkRk(pk, rk);
                return (T)item;
            }
            catch (Exception ex)
            {
                throw new ServiceException("", typeof(T).Name + rk + " data retrieval error");
            }
  ...

ServiceException类:

public class ServiceException : ApplicationException {     
        public Dictionary<string, string> Errors { get; set; }
        public ServiceException() : this(null) {}enter code here
        public ServiceException(string key, string message)
        {
            Errors = new Dictionary<string, string>(); 
            Errors.Add(key, message);
        }
        public ServiceException(Exception ex)
            : base("Service Exception", ex)
        {
            Errors = new Dictionary<string, string>();
        }
    }

然后在我的控制器中捕获了错误消息:

catch (Exception e) { log(e); }

最后在log方法中处理:

protected void log(Exception ex)
        {
            if (ex is ServiceException)
            {
                ModelState.Merge(((ServiceException)ex).Errors);  
            } else {
                Trace.Write(ex);
                ModelState.AddModelError("", "Database access error: " + ex.Message);
            }
        }

如果这是一个好的或坏的方法,任何人都可以评论。关于捕获内部异常,我之前有过评论。这是否可能,如果是这样,那么如何捕获并保留内部异常细节。

更新1

我修改了异常类,所以有一个构造函数需要ex。不确定这是否理想,但我认为它有效。关于如何改进的任何更多建议将不胜感激。

更新2

以下代码失败并显示一条消息

Error   2   Property or indexer 'System.Exception.InnerException' cannot be assigned to -- it is read only

我不知道如何解决这个问题。

public class ServiceException : ApplicationException {

    public Dictionary<string, string> Errors { get; set; }
    public ServiceException() : this(null) {}
    public ServiceException(Exception ex, string key, string message)
    {
        Errors = new Dictionary<string, string>();
        InnerException = ex;
        Errors.Add(key, message);
    }
    public ServiceException(string key, string message)
    {
        Errors = new Dictionary<string, string>(); 
        Errors.Add(key, message);
    }
    public ServiceException(Exception ex)
        : base("Service Exception", ex)
    {
        Errors = new Dictionary<string, string>();
    }
}

2 个答案:

答案 0 :(得分:1)

首先是

将捕获的异常包含为内部异常

所以而不是

throw new ServiceException("", typeof(T).Name + rk + " data retrieval error");

您应该设置内部异常。更改构造函数

public ServiceException(string key, string message, Exception innerException)
            :base(message, innerException)
        {
            Errors = new Dictionary<string, string>(); 
            Errors.Add(key, message);
        }

现在,

//form  your exception message
 var message = typeof(T).Name + rk + " data retrieval error";
//create service exception with the new overloaded constructor
 var exception  = new ServiceException("", typeof(T).Name + rk + " data retrieval error", message);
 throw exception;

这将保留您的内部异常。

答案 1 :(得分:1)

几乎在所有情况下,你都不应该捕捉异常。

你应该只捕捉你实际可以做的事情。

请参阅标记下的许多优秀问题:https://stackoverflow.com/questions/tagged/exception-handling?sort=votes

另外,请务必阅读Microsoft指南:“Design Guidelines for Exceptions”。