/// <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); }
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); }
/// <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(); } }
/// <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); } }
/// <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}"); } }
/// <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(); } }
// 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(); }); }
/// <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."); } }
static object DoSomethingThatThrows() { var specEx = new KnownException("Bare code threw exception"); SpecException = specEx; throw specEx; }
/// <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); } }
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); }
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); }
/// <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); }
/// <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; } } }
public static object Create( KnownException knownError, string correlationId) { return(new { CorrelationId = correlationId, knownError.ErrorCode, Data = knownError.GetData(), Error = knownError.ToString() }); }
/// <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."); } }
/// <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; } } }
/// <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(); }
/// <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); }
/// <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); }
/// <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)); }
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)); }
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)); }
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" }; }
/// <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); }