Was ist ein gutes globales exception-handling-Strategie für Unity3D?
Ich bin auf der Suche zu tun, einige Unity3D-scripting-Sachen, und ich würde gerne die Globale exception-handling-system. Dies ist nicht für den Betrieb in der release-version des Spiels, die Absicht ist, fangen Sie die Ausnahmen in Skripte und auch in der editor-Skripte und stellen Sie sicher, Sie werden weitergeleitet an eine Datenbank für die Analyse (und auch zum senden von E-Mail zum zuständigen Entwickler, so dass Sie beheben können Ihre shizzle).
In eine vanilla-C# - app habe ich ein try-catch um die Main-Methode. In WPF-würde ich Haken Sie eine oder mehrere der unbehandelte Ausnahme-events. In Der Einheit...?
Bisher die beste, die ich habe in der Lage zu kommen mit so etwas wie dieses:
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();
}
In anderen scripts, die ich ableiten BehaviourBase statt MonoBehavior und implementieren performUpdate() anstatt Update(). Ich habe nicht implementiert, die eine parallele version für den Editor clases, aber ich nehme an, ich müsste um das gleiche zu tun gibt.
Ich weiß nicht, wie diese Strategie allerdings, denn ich muss man es auf alle Skripts, die schnappen wir uns aus der community (und ich ' ll haben, um es durchzusetzen im team). Der Editor Skripte nicht über einen single point of entry vergleichbar MonoBehavior entweder, so gehe ich davon aus, dass ich hätte zu implementieren exception-sichere Versionen von wizards, Editoren und so weiter.
Ich habe gesehen, Vorschläge über den Fang von log-Meldungen (im Gegensatz zu Ausnahmen) mit - Anwendung.RegisterLogCallback, aber das macht mich unwohl, weil ich brauche, to analysieren Sie die debug-log-string, anstatt den Zugang zu der konkreten exceptions und stacktraces.
Also... was ist die richtige Sache zu tun?
InformationsquelleAutor theodox | 2013-02-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist eine funktionierende Implementierung der RegisterLogCallback, dass ich hier gefunden: http://answers.unity3d.com/questions/47659/callback-for-unhandled-exceptions.html
In meine eigene Implementierung, die ich es verwenden, um rufen Sie meine eigene MessageBox.Zeigen statt schreiben in eine log-Datei. Ich Ruf einfach SetupExceptionHandling aus jeder meiner Szenen.
Ich auch jetzt haben die den Fehler handler E-Mail mich über diese routine, so dass ich immer wissen Wann meine app abstürzt und so viel detail wie möglich.
InformationsquelleAutor Bryan Legend
Befestigen Sie dieses Skript in ein leeres game-Objekt in Ihrer Szene:
stellen Sie sicher, es gibt eine Instanz.
InformationsquelleAutor Bizhan
Ihnen genannten Anwendung.RegisterLogCallback, haben Sie versucht, es umzusetzen? Da die logging callback übergibt wieder einen stack-trace, ein Fehler, und ein Fehler-Typ (Warnung, Fehler, usw.).
Die Strategie, die Sie erläutert haben, wäre schwer zu implementieren, weil MonoBehaviours haben nicht nur eine single entry point. Sie würde zu behandeln OnTriggerEvent, OnCollisionEvent, OnGUI, und so weiter. Jede Verpackung, die Logik in einem exception-handler.
IMHO, exception handling ist eine schlechte Idee hier. Wenn Sie nicht sofort wieder werfen die Ausnahme, Sie werden am Ende Vermehrungs diesen Fehler in seltsame Wege. Vielleicht Foo stützt sich auf eine Bar, und eine Bar, Baz. Sagen Baz wirft eine exception, die abgefangen und protokolliert. Dann Bar wirft eine Ausnahme, weil der Wert, den es braucht, aus der Baz, ist falsch. Schließlich Foo eine exception wirft, weil der Wert, den es war die erste Bar ist ungültig.
Nein, ich bekomme dein Punkt, ich war nicht speziell bezogen auf eine release-version. Aber die eine oder andere Weise, wenn Sie das exception-handling, ist es da. So, wenn Sie Pflege 2 separaten code-Basis oder einen wirklich crufty BehaviourBase, bezweifle ich, es ist eine schnelle und einfache Lösung.
InformationsquelleAutor Jerdak
Unity devs einfach nicht liefern uns mit tools wie dem. Fangen Sie Ausnahmen intern im framework hier und da, und melden Sie als Zeichenfolgen, die uns Anwendung.logMessageReceived[Gewinde]. Also, wenn Sie brauchen, Ausnahmen zu passieren oder protokolliert werden, mit Ihrer eigenen Verarbeitung (keine Einheit), das ich denken kann:
verwenden Sie keine Rahmen, mechanik, aber verwenden Sie Ihre eigenen, so Ausnahme nicht abgefangen Rahmen
machen Sie Ihre eigenen Klasse die UnityEngine.ILogHandler:
öffentliche Schnittstelle ILogHandler
{
void LogFormat(LogType logType, Object context, string format, params object[] args);
void LogException(Exception exception, Object context);
}
Und verwenden Sie es, wie gesagt, in offiziellen docs zu protokollieren Ihre Ausnahmen. Aber so ist Sie nicht erhalten, nicht behandelte Ausnahmen und Ausnahmen protokolliert von plugins (ja, jemand melden Ausnahmen in frameworks, anstatt Sie zu werfen)
Oder Sie machen einen Vorschlag/Wunsch zu einer Einheit zu machen Debug.unityLogger (Debug.logger ist veraltet in der Einheit 2017) setter oder einen anderen Mechanismus, so können wir an unserer eigenen.
Einfach mit Reflexion. Aber es ist vorübergehend hack und funktioniert nicht wenn Einheit code ändern.
var Feld = typeof(UnityEngine.Debug -)
.GetField("s_Logger", BindingFlags.Static | BindingFlags.NonPublic);
Feld.SetValue(null, your_debug_logger);
Hinweis: Um die richtige stacktraces, die Sie benötigen, um StackTraceLogType im editor-Einstellungen/code ScriptOnly (meistens ist es das, was Sie brauchen, ich schrieb einen Artikel, wie es funktioniert) Und beim Bau für iOS, es wird gesagt, dass Script-Aufruf Optimierung festgelegt werden muss, um langsam und sicher
Wenn Sie interessiert sind, können Sie Lesen, wie die beliebten crash-Analyse-tool funktioniert. Wenn Sie einen Blick in crashlytics (crash report-tool für android/ios), als Sie erfahren, dass es intern verwendet, Anwendung.logMessageReceived und Anwendungsdomäne.CurrentDomain.UnhandledException-Ereignisse protokolliert werden managed C# - Ausnahmen.
Wenn Sie interessiert sind in den Beispielen auf das unity framework abfangen von Ausnahmen, kann man sich bei ExecuteEvents.Update Und ein weiterer Artikel von mir mit dem testen fallende Ausnahme in der Schaltfläche click-listener finden hier.
Einige Zusammenfassung auf der offiziellen Möglichkeiten, um sich unbehandelte Ausnahme:
I. Anwendung.logMessageReceived ausgelöst wird, wenn die exception passiert auf der main-thread. Es gibt Möglichkeiten, wie es zu geschehen:
Hinweis: stacktrace-string enthält "rethrow", wenn die original-Ausnahme inneren Ausnahmen
II. - Anwendung.logMessageReceivedThreaded ausgelöst wird, wenn die exception passiert auf jedem thread, einschließlich main (heißt es in docs) Hinweis: es muss eine thread-sichere
III. AppDomain.CurrentDomain.UnhandledException-zum Beispiel ausgelöst, wenn:
Rufen Sie den folgenden code im editor:
Aber es verursacht Absturz auf android 4.4.2 Version bauen, bei der Verwendung der Einheit 5.5.1f1
Hinweis: ich reproduziert einige bugs bei unity fehlt stackframes bei der Protokollierung von Ausnahmen und Behauptungen. Ich vorlegen ein von Ihnen.
InformationsquelleAutor
Können Sie mit einem plugin namens Reporter eine E-Mail erhalten Sie die Debug-Protokolle, Stack-trace und screen-capture auf das moment der nicht behandelte Fehler. Screen-capture-und stack-trace sind in der Regel genug, um herauszufinden, die Ursache des Fehlers. Für hartnäckige hinterhältige Fehler, du solltest dich mehr verdächtige Daten, zu bauen und zu warten, wieder für die Fehler.Ich Hoffe, das hilft.
InformationsquelleAutor yusuf baklacı