具有动态描述的异常助手工厂

Exception Helper factory with dynamic description

如何创建 ExceptionHelper class,它使用字符串模板为助手的调用者提供动态字符串元素?

这是我目前如何做的一个例子:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        try
        {
            throw ExceptionHelper.CreateTechnicalException(1001);
        }
        catch (TechnicalException ex)when (ex.ErrorSeverity > Severity.Warning)
        {
            Console.WriteLine($"{ex.ErrorCode} {ex.Message}");
        }

        try
        {
            throw ExceptionHelper.CreateTechnicalException(2002);
        }
        catch (TechnicalException ex)when (ex.ErrorSeverity > Severity.Warning)
        {
            Console.WriteLine($"{ex.ErrorCode} {ex.Message.Replace("$id$", "1").Replace("$type$", "myType")}");
        }
    }
}

public static class ExceptionHelper
{
    private static Dictionary<int, string> TechnicalErrorDictionary = new Dictionary<int, string>{{1001, "User with id $id$ does not exist"}, {1002, "Created user with id $id$"}, {2002, "User with id $id$ with type $type$ is invalid"}, {3003, "Unexpected server error"}, {4001, "Some text with $param1$ and another $param2$ included on $param3$"}};
    /// <exception cref = "KeyNotFoundException">the errorCode did not exist in dictionary</exception>
    public static TechnicalException CreateTechnicalException(int errorCode)
    {
        return new TechnicalException(errorCode, TechnicalErrorDictionary[errorCode]);
    }
}

public class TechnicalException : Exception
{
    public int ErrorCode
    {
        get;
    }

    public Severity ErrorSeverity
    {
        get;
    }

    public TechnicalException(int errorCode, string errorDescription): base (errorDescription)
    {
        ErrorCode = errorCode;
        ErrorSeverity = Severity.Error;
    }
}

public enum Severity
{
    Warning,
    Error
}

输出为:

> Hello World 
> 1001 User with id $id$ does not exist 
> 2002 User with id 1
> with type myType is invalid

是否有可能以更好的方式实现这一目标?

我觉得让每个使用此 Helper class 的开发人员对参数进行字符串替换的想法似乎太多余了,这有点消除了让 Helper class 来无论如何封装所有异常消息。

我希望 top 为开发人员提供某种字典,他们可以在其中通过 errorCode 选择异常,并且对于某些错误消息将使用参数。

dotNetFiddler: https://dotnetfiddle.net/BEFS80

这是其中一个不一定有 'right' 方法的事情,但我可以看到你的方法逐渐成为一个维护问题,所有这些代码无处不在...... .

对于这样的事情,我肯定会使用 Enum 而不是原始 int 错误代码 - 我不想尝试确定我应该抛出“9003”还是“9030”错误.如果您真的想那样做,请改用枚举,而不是试图引导用户记住参数的魔术字符串,只需使用显式构造函数创建 sub-类 of exception:

public enum ExceptionCode
{
    IncorrectUser = 1001,
    InvalidPassword= 1002,
    RanOutOfBeer = 9999,
}

public enum Severity
{
    Warning,
    Error
}

public class TechnicalException : Exception
{
    public ExceptionCode ErrorCode
    {
        get;
    }

    public Severity ErrorSeverity
    {
        get;
    }

    public TechnicalException(ExceptionCode errorCode, string errorDescription) : base(errorDescription)
    {
        ErrorCode = errorCode;
        ErrorSeverity = Severity.Error;
    }
}

public class InvalidUserException : TechnicalException
{
    public InvalidUserException(string username, string password) 
        : base(ExceptionCode.IncorrectUser, $"User {username} with password {password} is invalid")
    {

    }
}

public class test
{
    public void throwit()
    {
        throw new InvalidUserException("bob", "abc123");
    }
}

如果你这样做,你仍然可以 catch/list/log "TechnicalExceptions" 但代码更清晰、更简单,也更不脆弱。

您可以使用字符串格式实现此目的,并添加占位符 {0} {1}.. 示例:

    public static class ExceptionHelper
    {
        private static Dictionary<int, string> TechnicalErrorDictionary = new Dictionary<int, string> {{ 1001, "User with id {0} does not exist" }, { 1002, "Created user with id {0}" }, { 2002, "User with id {0} with type {1} is invalid" }, { 3003, "Unexpected server error" }, { 4001, "Some text with {0} and another {1} included on {2}" } };
        /// <exception cref = "KeyNotFoundException">the errorCode did not exist in dictionary</exception>
        public static TechnicalException CreateTechnicalException(int errorCode, params object[] para)
        {
            return new TechnicalException(errorCode, string.Format(TechnicalErrorDictionary[errorCode], para));
        }
    }

唯一的缺点是,开发人员必须确切知道每个错误代码所需的最少参数,否则可能会崩溃。