예제 #1
0
        private static void FirstChanceExceptionHandler(object sender, FirstChanceExceptionEventArgs args)
        {
            if (handlerActive.Value)
            {
                return;
            }

            bool oom = args.Exception is OutOfMemoryException;

            //In case of OOM, unload the Main.tile array and do immediate garbage collection.
            //If we don't do this, there will be a big chance that this method will fail to even quit the game, due to another OOM exception being thrown.
            if (oom)
            {
                Main.tile = null;

                GC.Collect();
            }

            try {
                handlerActive.Value = true;

                if (!oom)
                {
                    if (args.Exception == previousException ||
                        args.Exception is ThreadAbortException ||
                        ignoreSources.Contains(args.Exception.Source) ||
                        ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
                        ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
                    {
                        return;
                    }
                }

                var stackTrace = new StackTrace(true);
                PrettifyStackTraceSources(stackTrace.GetFrames());
                var traceString = stackTrace.ToString();

                if (!oom && ignoreContents.Any(traceString.Contains))
                {
                    return;
                }

                traceString = traceString.Substring(traceString.IndexOf('\n'));
                var exString = args.Exception.GetType() + ": " + args.Exception.Message + traceString;
                lock (pastExceptions) {
                    if (!pastExceptions.Add(exString))
                    {
                        return;
                    }
                }

                previousException = args.Exception;
                var msg = args.Exception.Message + " " + Language.GetTextValue("tModLoader.RuntimeErrorSeeLogsForFullTrace", Path.GetFileName(LogPath));
        #if CLIENT
                if (ModCompile.activelyModding)
                {
                    AddChatMessage(msg, Color.OrangeRed);
                }
        #else
                Console.ForegroundColor = ConsoleColor.DarkMagenta;
                Console.WriteLine(msg);
                Console.ResetColor();
        #endif
                tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);

                if (oom)
                {
                    const string error = "Game ran out of memory. You'll have to find which mod is consuming lots of memory, and contact the devs or remove it.";
                    Logging.tML.Fatal(error);
                    Interface.MessageBoxShow(error);
                    Environment.Exit(1);
                }
            }
            catch (Exception e) {
                tML.Warn("FirstChanceExceptionHandler exception", e);
            }
            finally {
                handlerActive.Value = false;
            }
        }
예제 #2
0
        private static void FirstChanceExceptionHandler(object sender, FirstChanceExceptionEventArgs args)
        {
            if (handlerActive.Value)
            {
                return;
            }

            try {
                handlerActive.Value = true;

                if (args.Exception == previousException ||
                    args.Exception is ThreadAbortException ||
                    ignoreSources.Contains(args.Exception.Source) ||
                    ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
                    ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
                {
                    return;
                }

                var stackTrace = new StackTrace(true);
                PrettifyStackTraceSources(stackTrace.GetFrames());
                var traceString = stackTrace.ToString();

                if (ignoreContents.Any(traceString.Contains))
                {
                    return;
                }

                traceString = traceString.Substring(traceString.IndexOf('\n'));
                var exString = args.Exception.GetType() + ": " + args.Exception.Message + traceString;
                lock (pastExceptions) {
                    if (!pastExceptions.Add(exString))
                    {
                        return;
                    }
                }

                previousException = args.Exception;
                var msg = args.Exception.Message + " " + Language.GetTextValue("tModLoader.RuntimeErrorSeeLogsForFullTrace", Path.GetFileName(LogPath));
        #if CLIENT
                if (ModCompile.activelyModding)
                {
                    AddChatMessage(msg, Color.OrangeRed);
                }
        #else
                Console.ForegroundColor = ConsoleColor.DarkMagenta;
                Console.WriteLine(msg);
                Console.ResetColor();
        #endif
                tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);

                if (args.Exception is OutOfMemoryException)
                {
                    Interface.MessageBoxShow("Game ran out of memory. You'll have to find which mod is consuming lots of memory, and contact the devs or remove it. (or go and find the 64bit version of tML)");
                    Environment.Exit(1);
                }
            }
            catch (Exception e) {
                tML.Warn("FirstChanceExceptionHandler exception", e);
            }
            finally {
                handlerActive.Value = false;
            }
        }