什么是Unity3D的良好全局异常处理策略? [英] What's a good global exception handling strategy for Unity3D?

查看:171
本文介绍了什么是Unity3D的良好全局异常处理策略?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑做一些Unity3D脚本编制工作,并且我想建立全局异常处理系统.这不是为了在游戏的发行版中运行,其目的是在用户脚本和编辑器脚本中捕获异常,并确保将异常转发到数据库进行分析(并向相关开发人员发送电子邮件,以便他们解决他们的问题).

I'm looking into doing some Unity3D scripting stuff, and I'd like to set up global exception handling system. This is not for running in the release version of the game, the intention is to catch exceptions in user scripts and also in editor scripts and make sure they are forwarded to a database for analysis (and also to send email to relevant devs so they can fix their shizzle).

在香草C#应用程序中,我会尝试绕过Main方法.在WPF中,我会钩住一个或多个未处理的异常事件.在Unity中...?

In a vanilla C# app I'd have a try-catch around the Main method. In WPF I'd hook one or more of the unhandled exception events. In Unity...?

到目前为止,我能想到的最好的东西是这样的:

So far the best I've been able to come up with is something like this:

using UnityEngine;
using System.Collections;

public abstract class BehaviourBase : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        try
        {
            performUpdate();
            print("hello");
        }
        catch (System.Exception e)
        {
            print(e.ToString());
        }

    }

    public abstract void performUpdate();

}

在其他脚本中,我派生BehaviourBase而不是MonoBehavior,并实现performUpdate()而不是Update().我还没有为Editor clase实现并行版本,但是我想我必须在其中做同样的事情.

In other scripts, I derive BehaviourBase instead of MonoBehavior and implement performUpdate() instead of Update(). I haven't implemented a parallel version for Editor clases but I assume I'd have to do the same thing there.

但是,我不喜欢这种策略,因为我必须将其反向移植到我们从社区获取的所有脚本中(并且我必须在团队中实施它).编辑器脚本也没有一个可与MonoBehavior媲美的入口点,因此我假设我必须实现向导,编辑器等的异常安全版本.

I don't like this strategy, however, because I'll have to backport it to any scripts we grab from the community (and I'll have to enforce it on the team). The Editor scripts don't have a single point of entry comparable to MonoBehavior either, so I assume I'd have to implement exception safe versions of wizards, editors and so on.

我已经看到有关使用 Application.RegisterLogCallback ,但这使我不舒服,因为我需要解析调试日志字符串,而不是访问实际的异常和堆栈跟踪.

I've seen suggestions about catching log messages (as opposed to exceptions) using Application.RegisterLogCallback, but this makes me uncomfortable because I'd need to parse the debug log string rather than having access to the actual exceptions and stacktraces.

那么...正确的做法是什么?

So... what's the right thing to do?

推荐答案

在这里找到了RegisterLogCallback的有效实现:

There is a working implementation of RegisterLogCallback that I found here: http://answers.unity3d.com/questions/47659/callback-for-unhandled-exceptions.html

在我自己的实现中,我用它来调用自己的MessageBox.Show而不是写入日志文件.我只是从每个场景中调用SetupExceptionHandling.

In my own implementation I use it to call my own MessageBox.Show instead of writing to a log file. I just call SetupExceptionHandling from each of my scenes.

    static bool isExceptionHandlingSetup;
    public static void SetupExceptionHandling()
    {
        if (!isExceptionHandlingSetup)
        {
            isExceptionHandlingSetup = true;
            Application.RegisterLogCallback(HandleException);
        }
    }

    static void HandleException(string condition, string stackTrace, LogType type)
    {
        if (type == LogType.Exception)
        {
            MessageBox.Show(condition + "\n" + stackTrace);
        }
    }

我现在也有错误处理程序通过此例程向我发送电子邮件,因此我总是知道我的应用崩溃时会获得尽可能多的详细信息.

I also now have the error handler email me via this routine, so I always know when my app crashes and get as much detail as possible.

        internal static void ReportCrash(string message, string stack)
    {
        //Debug.Log("Report Crash");
        var errorMessage = new StringBuilder();

        errorMessage.AppendLine("FreeCell Quest " + Application.platform);

        errorMessage.AppendLine();
        errorMessage.AppendLine(message);
        errorMessage.AppendLine(stack);

        //if (exception.InnerException != null) {
        //    errorMessage.Append("\n\n ***INNER EXCEPTION*** \n");
        //    errorMessage.Append(exception.InnerException.ToString());
        //}

        errorMessage.AppendFormat
        (
            "{0} {1} {2} {3}\n{4}, {5}, {6}, {7}x {8}\n{9}x{10} {11}dpi FullScreen {12}, {13}, {14} vmem: {15} Fill: {16} Max Texture: {17}\n\nScene {18}, Unity Version {19}, Ads Disabled {18}",
            SystemInfo.deviceModel,
            SystemInfo.deviceName,
            SystemInfo.deviceType,
            SystemInfo.deviceUniqueIdentifier,

            SystemInfo.operatingSystem,
            Localization.language,
            SystemInfo.systemMemorySize,
            SystemInfo.processorCount,
            SystemInfo.processorType,

            Screen.currentResolution.width,
            Screen.currentResolution.height,
            Screen.dpi,
            Screen.fullScreen,
            SystemInfo.graphicsDeviceName,
            SystemInfo.graphicsDeviceVendor,
            SystemInfo.graphicsMemorySize,
            SystemInfo.graphicsPixelFillrate,
            SystemInfo.maxTextureSize,

            Application.loadedLevelName,
            Application.unityVersion,
            GameSettings.AdsDisabled
        );

        //if (Main.Player != null) {
        //    errorMessage.Append("\n\n ***PLAYER*** \n");
        //    errorMessage.Append(XamlServices.Save(Main.Player));
        //}

        try {
            using (var client = new WebClient()) {
                var arguments = new NameValueCollection();
                //if (loginResult != null)
                //    arguments.Add("SessionId", loginResult.SessionId.ToString());
                arguments.Add("report", errorMessage.ToString());
                var result = Encoding.ASCII.GetString(client.UploadValues(serviceAddress + "/ReportCrash", arguments));
                //Debug.Log(result);
            }
        } catch (WebException e) {
            Debug.Log("Report Crash: " + e.ToString());
        }
    }

这篇关于什么是Unity3D的良好全局异常处理策略?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆