Alice52 / c-tutorial

The repository is about c, including c, csharp, cpp.
MIT License
0 stars 0 forks source link

[exception] handle exception #10

Open Alice52 opened 4 years ago

Alice52 commented 4 years ago

common

  1. should define a set of exception error code and message
  2. code should 8 bit, the type is int

    • start with different number has difference sense
  3. sample
public class ErrorMessages
{
    public const long A_ERROR_CODE = 99999001;
    public const string A_ERROR_MSG = "Input parameter invalid.";
}

public class ErrorResponse
{
    public string Code { get; set; }
    public string Message { get; set; }
    public object Parameters { get; set; }
}

usgae in .net core

  1. startup register
// this is add exception filter for global
services.AddMvc(options =>
{
    options.Filters.Add(typeof(ExceptionFilter));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
// set json handler
.AddJsonOptions(options =>
{
    options.SerializerSettings.ContractResolver =
        new CamelCasePropertyNamesContractResolver();
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
});
  1. IActionFilter
public class ActionFilter : IActionFilter
{
    private static string[] ignoreHeader = {
        "Sec-Fetch-Dest",
        "Sec-Fetch-Site",
        "Sec-Fetch-Mode",
        "Sec-Fetch-Dest",
        "Cookie",
        "Connection"
    };
    public void OnActionExecuted(ActionExecutedContext context)
    {
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        var controller = (ControllerBase)context.Controller;
        if (controller == null) return;
        var request = controller.Request;
        LogRequest(request, context.ActionArguments);
    }
    private void LogRequest(HttpRequest request, IDictionary<string, object> parameters)
    {
        StringBuilder content = new StringBuilder();
        content.Append(request.Method + " ")
                .Append(request.Scheme + "://")
                .Append(request.Host)
                .Append(request.Path + " ")
                .Append(request.Protocol)
                .AppendLine();

        var requestHeader = request.Headers;
        var headerIterator = requestHeader.GetEnumerator();
        while(headerIterator.MoveNext())
        {
            var currentItem = headerIterator.Current;
            if(Array.IndexOf(ignoreHeader, currentItem.Key) != -1) continue;
            content.Append(currentItem.Key + ": ")
                    .AppendLine(currentItem.Value.ToString());
        }

        content.AppendFormat("RequestBody: {0}", JsonConvert.SerializeObject(parameters, Formatting.Indented));
        LogUtil.Info(content.ToString());
    }
}
  1. IExceptionFilter
public class ExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        string message = context.Exception.InnerException == null
                ? context.Exception.Message : context.Exception.InnerException.Message;

        string errorCode = HttpStatusCode.InternalServerError.ToString();
        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        if (context.Exception.GetType() == typeof(xxxException))
        {
            var exception = (xxxException)context.Exception;
            errorCode = exception == null ? HttpStatusCode.BadRequest.ToString() : exception.Code.ToString();
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }
        else if (context.Exception.GetType() == typeof(ArgumentNullException) 
            || context.Exception.GetType() == typeof(ArgumentException)
            || context.Exception.GetType() == typeof(ArgumentOutOfRangeException)) 
        {
            errorCode = HttpStatusCode.BadRequest.ToString();
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }

        LogUtil.Error("exception message: " + message);
        LogUtil.Error(context.Exception.StackTrace);

        var request = context.HttpContext.Request;
        request.EnableRewind();
        request.Body.Position = 0;

        var requestBodyObject = string.Empty;

        using (StreamReader reader = new StreamReader(request.Body))
        {
            requestBodyObject = reader.ReadToEnd().ToString();
        }

        var errorResponse = new ErrorResponse()
        {
            Code = errorCode,
            Message = message,
            Parameters = JsonConvert.DeserializeObject<object>(requestBodyObject)
        };

        context.Result = new JsonResult(errorResponse);
    }
}