使用反射捕捉到TargetInvocationException异常

环境:Unity2017、.NET4.6

问题出现描述:自定义了JSON格式转换异常类,通过反射Invoke反射方法,抛出异常时,捕捉的异常是System.Reflection.TargetInvocationException而不是JSON格式转换异常。
源码简化如下:

/// <summary>
/// JSON格式转换类
/// </summary>
public static class JSonConvert
{
    public static void Convert()
    {
		throw new JsonToClassEX("转换失败");
    }
}
/// <summary>
/// JSON格式异常类
/// </summary>
public class JsonToClassEX : Exception
{
    public JsonToClassEX(string message) : base(message)
    {
    }
}

反射方法捕捉异常

/// <summary>
/// 反射方法捕捉异常
/// </summary>
public class NewBehaviourScript : MonoBehaviour
{
    void Start()
    {
        try
        {
            Type t = typeof(JSonConvert);
            MethodInfo method = t.GetMethod("Convert");
            method.Invoke(method.ReflectedType, null);
        }
        catch (JsonToClassEX e)
        {
            Debug.LogError("JsonToClassEX:" + e.Message);
        }
        catch (Exception e)
        {
            Debug.Log(e.GetType());
            Debug.Log(e.InnerException.GetType());
            Debug.LogError("Exception:" + e.Message);
        }
    }
}

输出结果:
输出结果
可以看到catch (JsonToClassEX e)块并没有进入,而是通过catch (Exception e)块捕捉到。
此外捕捉的异常是:System.Reflection.TargetInvocationException,而我们自定义的异常类被封成了异常的的InnerException属性。

分析原因:

这是由于CLR在调用反射方法,改变了异常,重新抛出了异常,但保留了JSON格式异常的堆栈信息。这是由于.NET内部机制导致。

解决方法:

第一种:在catch (Exception e)或catch (TargetInvocationException e) 处理异常
既然被封成了内部异常,那么我直接可以通过InnerException属性判断类型进行处理。

        catch (Exception e) when (e.InnerException.GetType() == typeof(JsonToClassEX))
        {
			//处理异常
        }

第二种:我就是想捕捉到JSON格式异常,我不要通过InnerException属性(真是任性呢)
可以通过在反射方法内捕捉,修改JSonConvert类Convert方法如:

    public static void Convert()
    {
        try
        {
            throw new JsonToClassEX("转换失败");
        }
        catch (Exception e)
        {
            Debug.LogWarning(e);
            //throw;如果想同时捕捉到argetInvocationException异常,请取消注释
        }

    }

这样捕捉到JsonToClassEX异常就不会抛出,若想继续捕捉到TargetInvocationException 异常就取消throw的注释。

posted @ 2021-01-29 10:49  20世纪少年  阅读(472)  评论(0编辑  收藏  举报