kreta/Framework/Exceptions/FrameworkException.cs
2024-03-13 00:33:46 +01:00

228 lines
7.6 KiB
C#

using System;
using System.Collections;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using Kreta.Framework.Localization;
using Kreta.Framework.Logging;
namespace Kreta.Framework
{
/// <summary>
/// A keretrendszer kivételeinek absztrakt ősosztálya.
/// </summary>
[FriendlyName(1000003, "Ismeretlen rendszerhiba történt.")]
[LogLevel(LogLevel.ERROR)]
[ErrorCode(Events.FRAMEWORK_EXCEPTION)]
[Serializable]
public abstract class FrameworkException : Exception
{
/// <summary>
/// Belső osztály a nyelvesítés támogatására.
/// </summary>
sealed class FrameworkExceptionLocalizer : ExceptionLocalizer
{
public override string Localize(Exception exception, CultureInfo cultureInfo)
{
return ReplaceParameters(exception as FrameworkException, base.Localize(exception, cultureInfo), cultureInfo);
}
static string ReplaceParameters(FrameworkException exception, string template, CultureInfo cultureInfo)
{
if (exception == null)
{
return template;
}
if (string.IsNullOrWhiteSpace(template))
{
return exception.Message;
}
string result = template;
foreach (DictionaryEntry entry in exception.Data)
{
string placeholder = "{" + entry.Key + "}";
object value = entry.Value;
result = result.Replace(placeholder, value != null ? Localizer.Localize(value, cultureInfo) : "N/A");
}
result = result.Replace("{InnerException}", exception.InnerException != null ? Localizer.Localize(exception.InnerException, cultureInfo) : "");
result = result.Replace("{Message}", exception.Message);
result = result.Replace("{Id}", exception.Id);
string formattedClientErrorCode = string.Format(CultureInfo.InvariantCulture, "{0} ({1})", exception.ClientErrorCode, (int)exception.ClientErrorCode);
result = result.Replace("{ClientErrorCode}", formattedClientErrorCode);
return result.Trim();
}
}
const string _errorMessage = "Unknown system error occurred.";
/// <summary>
/// Az osztály statikus konstruktora.
/// </summary>
static FrameworkException()
{
Localizer.SetLocalizer(typeof(FrameworkException), new FrameworkExceptionLocalizer());
}
/// <summary>
/// Az osztály konstruktora.
/// </summary>
/// <param name="message">A kivétel üzenete</param>
/// <param name="innerException">A belső kivétel</param>
protected FrameworkException(string message, Exception innerException)
: base(message, innerException)
{
// ReSharper disable DoNotCallOverridableMethodsInConstructor
Data["$Id"] = Guid.NewGuid().ToString();
Data["$IsLogged"] = false;
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
/// <summary>
/// Az osztály alapértelmezett konstruktora.
/// </summary>
protected FrameworkException()
: this(_errorMessage, null) { }
/// <summary>
/// Az osztály konstruktora.
/// </summary>
/// <param name="message">A kivétel üzenete</param>
protected FrameworkException(string message)
: this(message, null) { }
/// <summary>
/// Az osztály konstruktora.
/// </summary>
/// <param name="info">Sorosítási adatok</param>
/// <param name="context">Sorosítási adatfolyam</param>
protected FrameworkException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
/// <summary>
/// Beállítja egy paraméter értékét.
/// </summary>
/// <param name="key">A paraméter neve</param>
/// <param name="value">A paraméter értéke</param>
protected internal void SetValue(string key, object value)
{
if (value != null
&&
key != null
&&
key.Length > 0)
{
Data[key] = value;
}
}
/// <summary>
/// Naplózási szint.
/// </summary>
internal LogLevel LogLevel
{
get
{
LogLevelAttribute attribute =
GetType()
.GetCustomAttributes(typeof(LogLevelAttribute), true)
.OfType<LogLevelAttribute>()
.FirstOrDefault();
return attribute == null ? LogLevel.UNKNOWN : attribute.LogLevel;
}
}
/// <summary>
/// A kivétel üzenete.
/// </summary>
public override string Message
{
get
{
var result = base.Message;
foreach (DictionaryEntry entry in Data)
{
string placeholder = "{" + entry.Key + "}";
object value = entry.Value;
result = result.Replace(placeholder, value != null ? value.ToString() : "N/A");
}
return result;
}
}
/// <summary>
/// A kivétel adattartalma XML-ben.
/// </summary>
public string DataXml
{
get
{
var result = "<data>";
foreach (DictionaryEntry entry in Data.Cast<DictionaryEntry>().Where(entry => entry.Key.ToString() != "RequestXml"))
{
result += "<item name=\"";
result += entry.Key;
result += "\">";
object value = entry.Value;
string valuestring = value != null ? value.ToString() : "N/A";
result += valuestring;
result += "</item>";
}
result += "</data>";
return result;
}
}
/// <summary>
/// A kliensre visszaadott hibakód.
/// </summary>
internal Events ClientErrorCode
{
get
{
ErrorCodeAttribute attribute =
GetType()
.GetCustomAttributes(typeof(ErrorCodeAttribute), true)
.OfType<ErrorCodeAttribute>()
.FirstOrDefault();
return attribute == null ? Events.GENERAL : attribute.ErrorCode;
}
}
/// <summary>
/// A kivétel azonosítója, naplózáshoz használt.
/// </summary>
internal string Id
{
get
{
string result = Data["$Id"] as string;
if (result != null)
{
return result;
}
result = Guid.NewGuid().ToString();
Data["$Id"] = result;
return result;
}
}
/// <summary>
/// A kivétel naplózva lett-e már, vagy sem.
/// </summary>
internal bool IsLogged
{
get
{
return Equals(Data["$IsLogged"], true);
}
}
/// <summary>
/// Naplózottá minősíti a kivételt.
/// </summary>
internal void SetLogged()
{
Data["$IsLogged"] = true;
}
}
}