/// <summary>
        /// Attempts to write a string to the file.
        /// </summary>
        public KnownException TryWrite(string data)
        {
            KnownException exception = null;
            TextWriter     writer    = null;

            lock (fileLock)
            {
                try
                {
                    writer = MyAPIGateway.Utilities.WriteFileInLocalStorage(file, typeof(LocalFileIO));
                    writer.Write(data);
                    writer.Flush();
                }
                catch (Exception e)
                {
                    exception = new KnownException($"IO Error. Unable to write to {file}.", e);
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                }
            }

            return(exception);
        }
Beispiel #2
0
 public Log(KnownException ex)
 {
     this.Message = ex.CustomMessage;
     this.AdditionalInformation = ex;
     this.LogType    = LogInfoType.Exception;
     this.StackTrace = ex.Exception.StackTrace;
 }
        public IActionResult Index()
        {
            // 获取当前上下文里面报出的异常信息
            var exceptionHandlerPathFeature = HttpContext.Features.Get <IExceptionHandlerPathFeature>();

            var ex = exceptionHandlerPathFeature?.Error;

            // 特殊处理,尝试转换为 IKnownException
            var knownException = ex as IKnownException;

            // 对于未知异常,我们并不应该把错误异常完整地输出给客户端,而是应该定义一个特殊的信息 Unknown 传递给用户
            // Unknown 其实也是一个 IKnownException 的实现,它的 Message = "未知错误", ErrorCode = 9999
            // 也就是说我们在控制器 throw new Exception("报个错"); 就会看到错误信息
            if (knownException == null)
            {
                var logger = HttpContext.RequestServices.GetService <ILogger <MyExceptionFilterAttribute> >();
                // 我们看到的信息是未知错误,但是在我们的日志系统里面,我们还是记录的原有的异常信息
                logger.LogError(ex, ex.Message);
                knownException = KnownException.Unknown;
            }
            else// 当识别到异常是已知的业务异常时,输出已知的异常,包括异常消息,错误状态码和错误信息,就是在 IKnownException 中的定义
            {
                knownException = KnownException.FromKnownException(knownException);
            }
            return(View(knownException));
        }
        /// <summary>
        /// Attempts to retrieve the file data as a string.
        /// </summary>
        public KnownException TryRead(out string data)
        {
            KnownException exception = null;
            TextReader     reader    = null;

            data = null;

            lock (fileLock)
            {
                try
                {
                    reader = MyAPIGateway.Utilities.ReadFileInLocalStorage(file, typeof(LocalFileIO));
                    data   = reader.ReadToEnd();
                }
                catch (Exception e)
                {
                    data      = null;
                    exception = new KnownException($"IO Error. Unable to read from {file}.", e);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }
            }

            return(exception);
        }
        /// <summary>
        /// Attempts to retrieve the file data as a byte array. Requires data stream to begin with array size.
        /// </summary>
        public KnownException TryRead(out byte[] stream)
        {
            KnownException exception = null;
            BinaryReader   reader    = null;

            lock (fileLock)
            {
                try
                {
                    reader = MyAPIGateway.Utilities.ReadBinaryFileInLocalStorage(file, typeof(LocalFileIO));
                    stream = reader.ReadBytes(reader.ReadInt32());
                }
                catch (Exception e)
                {
                    stream    = null;
                    exception = new KnownException($"IO Error. Unable to read from {file}.", e);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }
            }

            return(exception);
        }
Beispiel #6
0
        /// <summary>
        /// Serializes server replies and sends them to the appropriate clients
        /// </summary>
        private void SendMessagesToClient()
        {
            if (serverOutgoing.Count > 0)
            {
                ExceptionHandler.WriteToLogAndConsole($"Sending {serverOutgoing.Count} message(s) to clients.", true);

                foreach (var clientMessages in serverOutgoing)
                {
                    byte[]         bin;
                    KnownException exception = Utils.ProtoBuf.TrySerialize(clientMessages.Item2, out bin);

                    if (exception == null)
                    {
                        exception = Utils.ProtoBuf.TrySerialize(new MessageContainer(true, bin), out bin);
                    }

                    if (exception == null)
                    {
                        MyAPIGateway.Multiplayer.SendMessageTo(serverHandlerID, bin, clientMessages.Item1);
                    }
                    else
                    {
                        ExceptionHandler.WriteToLogAndConsole($"Unable to serialize client message: {exception}");
                    }
                }

                // Reuse reply lists
                foreach (var list in serverOutgoing)
                {
                    replyListPool.Return(list.Item2);
                }

                serverOutgoing.Clear();
            }
        }
Beispiel #7
0
        /// <summary>
        /// Attempts to synchronously update log with message and adds a time stamp.
        /// </summary>
        public bool TryWriteToLogInternal(string message)
        {
            if (accessible)
            {
                message = $"[{DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss:ms")}] {message}";
                KnownException exception = logFile.TryAppend(message);

                if (exception != null)
                {
                    ExceptionHandler.SendChatMessage("Unable to update log; please check your file access permissions.");
                    accessible = false;
                    throw exception;
                }
                else
                {
                    ExceptionHandler.SendChatMessage("Log updated.");
                    accessible = true;
                    return(true);
                }
            }
            else
            {
                return(false);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Adds server reply for a given client message
        /// </summary>
        private void AddServerReply <T>(MyTuple <ulong, ClientMessage> message, T dataIn, ref ulong?currentClient)
        {
            ulong         clientID      = message.Item1;
            ClientMessage clientMessage = message.Item2;
            var           actionID      = clientMessage.actionID;

            byte[]         bin;
            KnownException exception = Utils.ProtoBuf.TrySerialize(dataIn, out bin);

            if (exception == null)
            {
                if (currentClient != clientID || currentClient == null)
                {
                    currentClient = clientID;
                    serverOutgoing.Add(new MyTuple <ulong, List <ServerReplyMessage> >(clientID, replyListPool.Get()));
                }

                var list = serverOutgoing[serverOutgoing.Count - 1].Item2;
                list.Add(new ServerReplyMessage(clientMessage.callbackID, bin));
            }
            else
            {
                ExceptionHandler.WriteToLogAndConsole($"Failed to serialize client reply: {exception}");
            }
        }
Beispiel #9
0
        /// <summary>
        /// Serializes client messages and sends them to the server
        /// </summary>
        private void SendMessagesToServer()
        {
            if (clientOutgoing.Count > 0)
            {
                ExceptionHandler.WriteToLogAndConsole($"Sending {clientOutgoing.Count} message(s) to server.", true);

                byte[]         bin;
                KnownException exception = Utils.ProtoBuf.TrySerialize(clientOutgoing, out bin);

                if (exception == null)
                {
                    exception = Utils.ProtoBuf.TrySerialize(new MessageContainer(false, bin), out bin);
                }

                if (exception == null)
                {
                    MyAPIGateway.Multiplayer.SendMessageToServer(serverHandlerID, bin);
                }
                else
                {
                    ExceptionHandler.WriteToLogAndConsole($"Unable to serialize server message: {exception}");
                }

                clientOutgoing.Clear();
            }
        }
Beispiel #10
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                //1 开发人员异常页 显示请求异常的详细信息。置于要捕获其异常的任何中间件前面
                //该页包括关于异常和请求的以下信息:
                //堆栈跟踪
                //查询字符串参数(如果有)
                //Cookie(如果有)
                //标头
                app.UseDeveloperExceptionPage();
            }
            else
            {
                //2 异常处理程序页
                //为生产环境配置自定义错误处理页,请使用异常处理中间件。
                //中间件
                //捕获并记录异常。
                //在备用管道中为指定的页或控制器重新执行请求。 如果响应已启动,则不会重新执行请求。
                app.UseExceptionHandler("/error");
                app.UseHsts();
            }

            app.UseExceptionHandler(errApp =>
            {
                errApp.Run(async context =>
                {
                    //3 访问异常lambda
                    //使用 IExceptionHandlerPathFeature 访问错误处理程序控制器或页中的异常和原始请求路径:
                    var exceptionHandlerPathFeature = context.Features.Get <IExceptionHandlerPathFeature>();
                    IKnownException knownException  = exceptionHandlerPathFeature.Error as IKnownException;
                    if (knownException == null)
                    {
                        var logger = context.RequestServices.GetService <ILogger <MyExceptionFilterAttribute> >();
                        logger.LogError(exceptionHandlerPathFeature.Error, exceptionHandlerPathFeature.Error.Message);
                        knownException = KnownException.Unknown;
                        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                    }
                    else
                    {
                        knownException = KnownException.FromKnownException(knownException);
                        context.Response.StatusCode = StatusCodes.Status200OK;
                    }
                    var jsonOptions = context.RequestServices.GetService <IOptions <JsonOptions> >();
                    context.Response.ContentType = "application/json; charset=utf-8";
                    await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(knownException, jsonOptions.Value.JsonSerializerOptions));
                });
            });

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
Beispiel #11
0
            /// <summary>
            /// Saves a given configuration to the save file in parallel.
            /// </summary>
            public void SaveStart(ConfigT cfg, bool silent = false)
            {
                if (!SaveInProgress)
                {
                    if (!silent)
                    {
                        ExceptionHandler.SendChatMessage("Saving configuration...");
                    }
                    SaveInProgress = true;

                    EnqueueTask(() =>
                    {
                        cfg.Validate();
                        KnownException exception = TrySave(cfg);

                        if (exception != null)
                        {
                            EnqueueAction(() =>
                                          SaveFinish(false, silent));

                            throw exception;
                        }
                        else
                        {
                            EnqueueAction(() =>
                                          SaveFinish(true, silent));
                        }
                    });
                }
                else
                {
                    ExceptionHandler.SendChatMessage("Save operation already in progress.");
                }
            }
Beispiel #12
0
            static object DoSomethingThatThrows()
            {
                var specEx = new KnownException("Bare code threw exception");

                SpecException = specEx;

                throw specEx;
            }
Beispiel #13
0
 /// <summary>
 /// Handles the CMS exception.
 /// </summary>
 /// <param name="ex">The exception.</param>
 /// <param name="command">The command.</param>
 /// <param name="request">The request.</param>
 private static void HandleCmsException(KnownException ex, ICommandBase command, object request = null)
 {
     Log.Error(FormatCommandExceptionMessage(command, request), ex);
     if (command.Context != null)
     {
         command.Context.Messages.AddError(Global.Message_InternalServerErrorPleaseRetry);
     }
 }
Beispiel #14
0
        public bool CreateEssenticalFolder()
        {
            bool isSuccess = false;

            try
            {
                List <UriParameter> paras = new List <UriParameter>()
                {
                    this.EssentialParameters.Output,
                    this.EssentialParameters.Log
                };

                foreach (UriParameter p in paras)
                {
                    string docFolder         = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    string inputRelativePath = Path.GetFileName(this.EssentialParameters.Input.URI.LocalPath);
                    if (!p.ValidateResult.IsValid)
                    {
                        DirectoryInfo dirInfo = Directory.CreateDirectory(p.Value);
                        // try to create folder at expected location
                        if (dirInfo.Exists)
                        {
                            p.ValidateResult.IsValid = true;
                            p.URI = new Uri(dirInfo.FullName);
                        }

                        // create folder at default location
                        else
                        {
                            string path = Path.Combine(docFolder, inputRelativePath, p.Name);
                            p.URI = new Uri(path);
                            if (Directory.CreateDirectory(path).Exists)
                            {
                                p.ValidateResult.IsRevised = true;
                                p.ValidateResult.IsValid   = true;
                            }
                            else
                            {
                                throw new Exception("Can not create folders.");
                            }
                        }
                    }
                }

                isSuccess = true;
            }
            catch (Exception ex)
            {
                KnownException exception = new KnownException()
                {
                    Exception = ex,
                    Type      = ExceptionType.Error_Creating_Folder
                };
                ExceptionHandler.HandleExceptions(exception);
            }

            return(isSuccess);
        }
Beispiel #15
0
        public void FormatKnownException_Test()
        {
            KnownException ex = new KnownException(1, "已知异常");

            Assert.True(ex != null);
            string msg = ex.Format();

            Assert.Equal(1, ex.Code);
            Assert.Contains("已知异常", msg);
        }
Beispiel #16
0
            /// <summary>
            /// Attempts to save current configuration to a file.
            /// </summary>
            private KnownException TrySave(ConfigT cfg)
            {
                string         xmlOut;
                KnownException exception = Utils.Xml.TrySerialize(cfg, out xmlOut);

                if (exception == null && xmlOut != null)
                {
                    exception = cfgFile.TryWrite(xmlOut);
                }

                return(exception);
            }
Beispiel #17
0
            /// <summary>
            /// Creates a duplicate of the config file starting with a new file name starting with "old_"
            /// if one exists.
            /// </summary>
            private void Backup()
            {
                if (cfgFile.FileExists)
                {
                    KnownException exception = cfgFile.TryDuplicate($"old_" + cfgFile.file);

                    if (exception != null)
                    {
                        throw exception;
                    }
                }
            }
Beispiel #18
0
 public static object Create(
     KnownException knownError,
     string correlationId)
 {
     return(new
     {
         CorrelationId = correlationId,
         knownError.ErrorCode,
         Data = knownError.GetData(),
         Error = knownError.ToString()
     });
 }
Beispiel #19
0
            /// <summary>
            /// Loads the current configuration in parallel.
            /// </summary>
            public void LoadStart(Action <ConfigT> UpdateConfig, bool silent = false)
            {
                if (!SaveInProgress)
                {
                    SaveInProgress = true;
                    if (!silent)
                    {
                        ExceptionHandler.SendChatMessage("Loading configuration...");
                    }

                    EnqueueTask(() =>
                    {
                        ConfigT cfg = null;
                        KnownException loadException = null;

                        // Load and validate
                        if (cfgFile.FileExists)
                        {
                            loadException = TryLoad(out cfg);
                            cfg           = ValidateConfig(cfg);
                        }
                        else
                        {
                            cfg = Defaults;
                        }

                        // Enqueue callback
                        EnqueueAction(() =>
                                      UpdateConfig(cfg));

                        // Write validated config back to the file
                        TrySave(cfg);

                        if (loadException != null)
                        {
                            EnqueueAction(() =>
                                          LoadFinish(false, silent));

                            throw loadException;
                        }
                        else
                        {
                            EnqueueAction(() =>
                                          LoadFinish(true, silent));
                        }
                    });
                }
                else
                {
                    ExceptionHandler.SendChatMessage("Save operation already in progress.");
                }
            }
Beispiel #20
0
            /// <summary>
            /// Saves the current configuration synchronously.
            /// </summary>
            public void Save(ConfigT cfg)
            {
                if (!SaveInProgress)
                {
                    cfg.Validate();
                    KnownException exception = TrySave(cfg);

                    if (exception != null)
                    {
                        throw exception;
                    }
                }
            }
Beispiel #21
0
        /// <summary>
        /// Parses messages recieved into separate client and server message lists
        /// </summary>
        private void ParseIncommingMessages()
        {
            int errCount = 0;

            receivedServerMessages.Clear();
            receivedClientMessages.Clear();

            // Deserialize client messages and keep a running count of errors
            for (int i = 0; i < incomingMessages.Count; i++)
            {
                MessageContainer container;
                KnownException   exception = Utils.ProtoBuf.TryDeserialize(incomingMessages[i].message, out container);

                if (exception != null)
                {
                    errCount++;
                }
                else if (container.isFromServer)
                {
                    ServerReplyMessage[] serverReplies;
                    exception = Utils.ProtoBuf.TryDeserialize(container.message, out serverReplies);

                    receivedServerMessages.AddRange(serverReplies);
                }
                else
                {
                    ClientMessage[] clientMessages;
                    exception = Utils.ProtoBuf.TryDeserialize(container.message, out clientMessages);

                    receivedClientMessages.EnsureCapacity(receivedClientMessages.Count + clientMessages.Length);

                    for (int j = 0; j < clientMessages.Length; j++)
                    {
                        receivedClientMessages.Add(new MyTuple <ulong, ClientMessage>(incomingMessages[i].plyID, clientMessages[j]));
                    }
                }

                if (exception != null)
                {
                    errCount++;
                }
            }

            if (errCount > 0)
            {
                ExceptionHandler.WriteToLogAndConsole($"Unable to parse {errCount} of {incomingMessages.Count} message(s).");
            }

            incomingMessages.Clear();
        }
Beispiel #22
0
        /// <summary>
        /// Creates a local duplicate of a file with a given name.
        /// </summary>
        public KnownException TryDuplicate(string newName)
        {
            string         data;
            KnownException exception = TryRead(out data);
            LocalFileIO    newFile;

            if (exception == null && data != null)
            {
                newFile   = new LocalFileIO(newName);
                exception = newFile.TryWrite(data);
            }

            return(exception);
        }
Beispiel #23
0
        /// <summary>
        /// Attempts to append string to an existing local file.
        /// </summary>
        public KnownException TryAppend(string data)
        {
            string         current;
            KnownException exception = TryRead(out current);

            if (exception == null && current != null)
            {
                current  += data;
                exception = TryWrite(current);
            }
            else
            {
                exception = TryWrite(data);
            }

            return(exception);
        }
Beispiel #24
0
            /// <summary>
            /// Attempts to load config file and creates a new one if it can't.
            /// </summary>
            private KnownException TryLoad(out ConfigT cfg)
            {
                string         data;
                KnownException exception = cfgFile.TryRead(out data);

                cfg = null;

                if (exception != null || data == null)
                {
                    return(exception);
                }
                else
                {
                    exception = Utils.Xml.TryDeserialize(data, out cfg);
                }

                return(exception);
            }
        public ActionResult Get()
        {
            IKnownException knownException;
            var             exceptionHandlerFeature = HttpContext.Features.Get <IExceptionHandlerFeature>();
            var             exception = exceptionHandlerFeature?.Error;

            if (exception is IKnownException ex)
            {
                knownException = ex;
            }
            else
            {
                //未知錯誤必須記錄log
                knownException = KnownException.UnKnow();
            }

            return(Content(knownException.ToString()));
        }
        /// <summary>
        /// 异常处理页
        /// </summary>
        /// <returns></returns>
        //[Route("{id}")]
        public IActionResult Index(int id)
        {
            var exception     = HttpContext.Features.Get <IExceptionHandlerPathFeature>();
            var ex            = exception?.Error;
            var knowException = ex as IKnownException;

            if (knowException == null)
            {
                var logger = HttpContext.RequestServices.GetService <ILogger <MyExceptionFilterAttribute> >();
                logger.LogError(ex, ex.Message);
                knowException = KnownException.Unknown;
            }
            else
            {
                knowException = KnownException.FromKnownException(knowException);
            }
            return(View(knowException));
        }
Beispiel #27
0
        public IActionResult Index()
        {
            var feature        = HttpContext.Features.Get <IExceptionHandlerPathFeature>();
            var err            = feature?.Error;
            var knownException = err as IKnownException;

            if (knownException == null)
            {
                //var logger = HttpContext.RequestServices.GetService<ILogger<ErrorController>>();
                _logger.LogError(err, err.Message);
                knownException = KnownException.UnKnown;
            }
            else
            {
                knownException = KnownException.FromKnownException(knownException);
            }
            return(View(knownException));
        }
Beispiel #28
0
        public IActionResult Error1()
        {
            var exceptionHandlerPathFeature = HttpContext.Features.Get <IExceptionHandlerPathFeature>();
            var ex             = exceptionHandlerPathFeature?.Error;
            var knownException = ex as IknownException;

            if (knownException == null)
            {
                var logger = HttpContext.RequestServices.GetService <ILogger <HomeController> >();
                logger.LogError(ex, ex.Message);
                knownException = KnownException.Unknown;
            }
            else
            {
                knownException = KnownException.FromKnownException(knownException);
            }

            return(View(knownException));
        }
Beispiel #29
0
        public void OnException(ExceptionContext context)
        {
            var knowException = context.Exception as IKnownException;

            context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
            if (knowException == null)
            {
                // 紀錄log
                _logger.LogError(context.Exception.ToString());
                context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
                ;
                knowException = KnownException.UnKnow();
            }

            context.Result = new JsonResult(KnownException.FromKnownException(knowException))
            {
                ContentType = "application/json;charset=utf-8"
            };
        }
Beispiel #30
0
            /// <summary>
            /// Loads the current configuration synchronously.
            /// </summary>
            public ConfigT Load(bool silent = false)
            {
                ConfigT        cfg           = null;
                KnownException loadException = null;

                if (!SaveInProgress)
                {
                    SaveInProgress = true;

                    if (!silent)
                    {
                        ExceptionHandler.SendChatMessage("Loading configuration...");
                    }

                    if (cfgFile.FileExists)
                    {
                        loadException = TryLoad(out cfg);
                        cfg           = ValidateConfig(cfg);
                    }
                    else
                    {
                        cfg = Defaults;
                    }

                    TrySave(cfg);

                    if (loadException != null)
                    {
                        ExceptionHandler.WriteToLog(loadException.ToString());
                    }
                    else if (!silent)
                    {
                        ExceptionHandler.SendChatMessage("Configuration loaded.");
                    }
                }
                else
                {
                    ExceptionHandler.SendChatMessage("Save operation already in progress.");
                }

                SaveInProgress = false;
                return(cfg);
            }