Caliburn.Micro: Recovering from Exception in IResult

我只是一个虾纸丫 提交于 2019-12-06 07:55:06

Both Rob Eisenberg and Marco Amendola have provided possible solutions in the CodePlex forum.

I have chosen to take Marco's RescueAttribute from his filters implementation and modify it slightly to allow execution of further IResult from the rescue method. This is the required change to RescueAttribute.HandleException

protected override bool HandleException(ActionExecutionContext context,
                                        Exception ex)
{
    var method = context.Target
                        .GetType()
                        .GetMethod(MethodName, new[] { typeof(Exception) });
    if (method == null) return false;

    try
    {
        var result = method.Invoke(context.Target, new object[] { ex });

        if (result is bool)
            return (bool) result;

        if (result is IResult)
            result = new[] { result as IResult };
        if (result is IEnumerable<IResult>)
            Coroutine.Execute(((IEnumerable<IResult>) result).GetEnumerator(), context);
        else if (result is IEnumerator<IResult>)
            Coroutine.Execute(((IEnumerator<IResult>) result), context);

        return true;
    }
    catch
    {
        return false;
    }
}

this allows the following in my VM:

public IEnumerable<IResult> Rescue(Exception ex)
{
    yield return Busy.MakeNotBusy();
    // in practice pass exception details through to notification
    yield return new NotificationPopup("Save station failed");
}

[Rescue]
public IEnumerable<IResult> SaveStation()
{ 
    yield return Busy.MakeBusy();
    yield return new StationSave(_station);
    yield return Busy.MakeNotBusy();
    yield return Show.Tab<StationBrowseViewModel>();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!