/// <summary> /// Returns an <see cref="ErrCodeInfo" /> object for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <param name="AErrorMessagePlaceholderTexts">Array whose strings are placed into placeholders /// which are found in the ErrorCode's ErrorMessageText (optional Argument!)</param>. /// <returns>An <see cref="ErrCodeInfo" /> object which holds information about /// the specified error code, or null, if the error code was not found.</returns> public static ErrCodeInfo GetErrorInfo(string AErrorCode, string[] AErrorMessagePlaceholderTexts) { ErrCodeInfo ReturnValue = GetErrorInfo(AErrorCode); string ErrorMessageText; if (ReturnValue.ErrorMessageText != String.Empty) { ErrorMessageText = ReturnValue.ErrorMessageText; } else { if ((AErrorMessagePlaceholderTexts != null) && (AErrorMessagePlaceholderTexts.Length > 0)) { ErrorMessageText = AErrorMessagePlaceholderTexts[0]; AErrorMessagePlaceholderTexts = null; } else { throw new ArgumentException("The error code's ErrorMessageText is an empty string, therefore this overload can't be used. " + "Use the overload that has the Argument 'AErrorMessageText' instead, or define the error code's ErrorMessageText"); } } return(GetErrorInfo(AErrorCode, ErrorMessageText, AErrorMessagePlaceholderTexts)); }
/// <summary> /// Returns an <see cref="ErrCodeInfo" /> object for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <param name="AErrorMessageText">Set this to <see cref="String.Empty" /> to use the /// <see cref="ErrCodeInfo.ShortDescription" /> of the <see cref="ErrCodeInfo" />, set it to any other string and /// this will be displayed instead.</param> /// <param name="AErrorMessagePlaceholderTexts">Array whose strings are placed into placeholders which are found in /// <paramref name="AErrorMessageText" /> (optional Argument!)</param>. /// <param name="AErrorTitlePlaceholderTexts">Array whose strings are placed into placeholders which are found in /// the ErrorCode's ErrorTitle (optional Argument!)</param>. /// /// <returns>An <see cref="ErrCodeInfo" /> object which holds information about /// the specified error code, or null, if the error code was not found.</returns> public static ErrCodeInfo GetErrorInfo(string AErrorCode, string AErrorMessageText, string[] AErrorMessagePlaceholderTexts = null, string[] AErrorTitlePlaceholderTexts = null) { ErrCodeInfo FoundErrInfo; ErrCodeInfo ReturnValue = null; string ErrorMessageText; string ErrorTitleText = String.Empty; if (AErrorMessageText == null) { throw new ArgumentException("Argument 'AErrorMessageText' must not be null"); } FoundErrInfo = GetErrorInfo(AErrorCode); if (AErrorMessageText == String.Empty) { if (FoundErrInfo.ErrorMessageText == String.Empty) { throw new ArgumentException( "Argument 'AErrorMessageText' must not be an empty string if the error code's ErrorMessageText is an empty string, too"); } else { ErrorMessageText = FoundErrInfo.ErrorMessageText; } } else { ErrorMessageText = AErrorMessageText; } if ((FoundErrInfo != null)) { if ((AErrorMessagePlaceholderTexts != null) && (AErrorMessagePlaceholderTexts.Length != 0)) { ErrorMessageText = String.Format(ErrorMessageText, AErrorMessagePlaceholderTexts); } ErrorTitleText = FoundErrInfo.ErrorMessageTitle; if ((AErrorTitlePlaceholderTexts != null) && (AErrorTitlePlaceholderTexts.Length != 0)) { ErrorTitleText = String.Format(ErrorTitleText, AErrorTitlePlaceholderTexts); } } ReturnValue = new ErrCodeInfo(FoundErrInfo.ErrorCode, FoundErrInfo.ErrorCodeConstantClass, FoundErrInfo.ErrorCodeConstantName, FoundErrInfo.ShortDescription, FoundErrInfo.FullDescription, ErrorMessageText, ErrorTitleText, FoundErrInfo.Category, FoundErrInfo.HelpID); return(ReturnValue); }
/// <summary> /// Retrieves the <see cref="ErrCodeInfo" /> for a given Error Code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <returns><see cref="ErrCodeInfo" /> for the Error Code specified in <paramref name="AErrorCode" /> or /// null if the Error Code isn't found in any of the registered Types or in the calling Class.</returns> public static ErrCodeInfo RetrieveErrCodeInfo(string AErrorCode) { ErrCodeInfo ReturnValue = null; Type CheckedType = null; int Counter2 = 0; if (ErrorCodeCatalogue.ContainsKey(AErrorCode)) { ReturnValue = (ErrCodeInfo)ErrorCodeInventory.ErrorCodeCatalogue[AErrorCode]; } else { // Error Code wasn't found -> need to check whether it was registered and included in the Error Code Inventory! for (int Counter = 0; Counter < RegisteredTypes.Count; Counter++) { CheckedType = RegisteredTypes[Counter]; if (!AreTypesErrorCodesCatalogued(CheckedType.Name)) { BuildErrorCodeInventory(CheckedType); } if (ErrorCodeCatalogue.ContainsKey(AErrorCode)) { ReturnValue = (ErrCodeInfo)ErrorCodeInventory.ErrorCodeCatalogue[AErrorCode]; break; } } if (ReturnValue == null) { // 'On-the-fly' adding to the 'registered types' of the Type that called this Method. // This is needed for the case where an Error Code is defined in any Type other than the pre-registered Types. do { Counter2++; CheckedType = new System.Diagnostics.StackTrace(false).GetFrame(Counter2).GetMethod().DeclaringType; } while (CheckedType.FullName == "Ict.Common.ErrorCodes"); if (!AreTypesErrorCodesCatalogued(CheckedType.Name)) { BuildErrorCodeInventory(CheckedType); // Recursive self-calling! ReturnValue = RetrieveErrCodeInfo(AErrorCode); } } } return(ReturnValue); }
/// <summary> /// Returns the error Help ID for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <returns>Error Help ID for a specified error code.</returns> public static string GetErrorHelpID(string AErrorCode) { ErrCodeInfo EInfo = GetErrorInfo(AErrorCode); if (EInfo != null) { return(EInfo.HelpID); } else { return(String.Empty); } }
/// <summary> /// Returns the error description (FullDescription) for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <returns>Error description (FullDescription) for a specified error code, or /// <see cref="System.String.Empty" /> if the error code was not found.</returns> public static string GetErrorDescription(string AErrorCode) { ErrCodeInfo EInfo = GetErrorInfo(AErrorCode); if (EInfo != null) { return(EInfo.FullDescription); } else { return(String.Empty); } }
/// <summary> /// Returns an <see cref="ErrCodeInfo" /> object for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <returns>An <see cref="ErrCodeInfo" /> object which holds information about /// the specified error code, or null, if the error code was not found.</returns> public static ErrCodeInfo GetErrorInfo(string AErrorCode) { ErrCodeInfo ReturnValue = null; ReturnValue = ErrorCodeInventory.RetrieveErrCodeInfo(AErrorCode); if (ReturnValue == null) { throw new EErrorCodeNotRegisteredException(String.Format("Error Code '{0}' could not be found in any of the registered Types!", AErrorCode) + Environment.NewLine + "Registered Types: " + ErrorCodeInventory.ListRegisteredTypes() + "."); } return(ReturnValue); }
private static void ProcessFile(CSParser AParsedFile, ref Dictionary <string, ErrCodeInfo>AErrorCodes) { ErrCodeInfo ErrCodeDetails = null; string ErrCodeValue; string ShortDescription = String.Empty; string LongDescription = String.Empty; ErrCodeCategory ErrCodeCat; foreach (TypeDeclaration t in AParsedFile.GetClasses()) { foreach (object child in t.Children) { if (child is INode) { INode node = (INode)child; Type type = node.GetType(); if (type.Name == "FieldDeclaration") { FieldDeclaration fd = (FieldDeclaration)node; foreach (VariableDeclaration vd in fd.Fields) { foreach (AttributeSection attrSection in fd.Attributes) { foreach (ICSharpCode.NRefactory.Ast.Attribute attr in attrSection.Attributes) { LongDescription = String.Empty; if (attr.Name == "ErrCodeAttribute") { ErrCodeValue = ((PrimitiveExpression)vd.Initializer).Value.ToString(); if (ErrCodeValue.EndsWith("V")) { ErrCodeCat = ErrCodeCategory.Validation; } else if (ErrCodeValue.EndsWith("N")) { ErrCodeCat = ErrCodeCategory.NonCriticalError; } else { ErrCodeCat = ErrCodeCategory.Error; } // TLogging.Log(""); // TLogging.Log(""); // TLogging.Log(""); // TLogging.Log(vd.Name + " = " + ((PrimitiveExpression)vd.Initializer).Value.ToString()); foreach (Expression e in attr.PositionalArguments) { // TLogging.Log("ShortDescription: " + ShortDescription); ShortDescription = ((PrimitiveExpression)e).Value.ToString(); } foreach (Expression e in attr.NamedArguments) { if (((NamedArgumentExpression)e).Name == "FullDescription") { LongDescription = ExpressionToString(((NamedArgumentExpression)e).Expression); } // TLogging.Log("NamedArgumentExpression Name: " + LongDescription); } ErrCodeDetails = new ErrCodeInfo(ErrCodeValue, t.Name, vd.Name, ShortDescription, LongDescription, String.Empty, String.Empty, ErrCodeCat, String.Empty, false); AErrorCodes.Add(ErrCodeValue, ErrCodeDetails); } } } } } } } } }
public void TestErrorCodes() { ErrCodeInfo ExpectedResult = null; ErrCodeInfo TestResult = null; string Testname; string VerificationProblemListing; #region GetErrorInfo EDuplicateErrorCodeException TestException1 = Assert.Throws <EDuplicateErrorCodeException>( delegate { ErrorCodes.GetErrorInfo("TEST.99995x", new string[] { }); }); Assert.That(TestException1.Message, Is.EqualTo("An attempt to add Error Code with value 'TEST.99995x' through constant " + "'Ict.Common.Testing.TTestCommon.ERR_TESTONLY6' failed, as there is already an Error Code with that value: it is defined through constant " + "'Ict.Common.Testing.TTestCommon.ERR_TESTONLY5'.")); ArgumentException TestException2 = Assert.Throws <ArgumentException>( delegate { ErrorCodes.GetErrorInfo("TEST.99999V", null, new string[] { }); }); Assert.That(TestException2.Message, Is.EqualTo("Argument 'AErrorMessageText' must not be null")); ArgumentException TestException3 = Assert.Throws <ArgumentException>( delegate { ErrorCodes.GetErrorInfo("TEST.99998V", String.Empty, new string[] { "asdf" }); }); Assert.That(TestException3.Message, Is.EqualTo("Argument 'AErrorMessageText' must not be an empty string if the error code's ErrorMessageText is an empty string, too")); EErrorCodeNotRegisteredException TestException4 = Assert.Throws <EErrorCodeNotRegisteredException>( delegate { ErrorCodes.GetErrorInfo("TEST.99996V"); }); Assert.That(TestException4.Message, Is.StringStarting("Error Code 'TEST.99996V' could not be found in any of the registered Types!")); ArgumentException TestException5 = Assert.Throws <ArgumentException>( delegate { ErrorCodes.GetErrorInfo("TEST.99996N", new string[] { }); }); Assert.That(TestException5.Message, Is.EqualTo("The error code's ErrorMessageText is an empty string, therefore this overload can't be used. " + "Use the overload that has the Argument 'AErrorMessageText' instead, or define the error code's ErrorMessageText")); Testname = "Replacing ErrorMessageText placeholder with AErrorMessagePlaceholderTexts Array content"; TestResult = ErrorCodes.GetErrorInfo("TEST.99998V", new string[] { "test only" }); ExpectedResult = new ErrCodeInfo("TEST.99998V", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY2", "Date may not be empty.", "The date may not be empty.", "test only", String.Empty, ErrCodeCategory.Validation, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "Empty AErrorMessageText and empty AErrorMessagePlaceholderTexts Array"; TestResult = ErrorCodes.GetErrorInfo("TEST.99997V", String.Empty, new string[] { }); ExpectedResult = new ErrCodeInfo("TEST.99997V", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY3", "Value is no longer assignable.", String.Empty, "The code '{0}' is no longer active.\r\nDo you still want to use it?", "Invalid Data Entered", ErrCodeCategory.Validation, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "Empty AErrorMessageText and AErrorMessagePlaceholderTexts Array with one value"; TestResult = ErrorCodes.GetErrorInfo("TEST.99997V", String.Empty, new string[] { "test only" }); ExpectedResult = new ErrCodeInfo("TEST.99997V", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY3", "Value is no longer assignable.", String.Empty, "The code 'test only' is no longer active.\r\nDo you still want to use it?", "Invalid Data Entered", ErrCodeCategory.Validation, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "Empty AErrorMessagePlaceholderTexts Array"; TestResult = ErrorCodes.GetErrorInfo("TEST.99999V"); ExpectedResult = ErrorCodes.GetErrorInfo("TEST.99999V"); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "Empty AErrorMessagePlaceholderTexts Array"; TestResult = ErrorCodes.GetErrorInfo("TEST.99999V", Testname, new string[] { }); ExpectedResult = ErrorCodes.GetErrorInfo("TEST.99999V", Testname); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "Empty AErrorMessagePlaceholderTexts Array"; TestResult = ErrorCodes.GetErrorInfo("TEST.99999V", String.Empty, new string[] { }); ExpectedResult = ErrorCodes.GetErrorInfo("TEST.99999V"); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "AErrorTitlePlaceholderTexts Array with one value"; TestResult = ErrorCodes.GetErrorInfo("TEST.99994V", String.Empty, new string[] { "My Testcode" }, new string[] { "TestCode" }); ExpectedResult = new ErrCodeInfo("TEST.99994V", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY7", "Value is no longer assignable.", String.Empty, "The code 'My Testcode' is no longer active.\r\nDo you still want to use it?", "Invalid TestCode Entered", ErrCodeCategory.Validation, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "No AErrorMessageText and AErrorMessagePlaceholderTexts Array with one value"; TestResult = ErrorCodes.GetErrorInfo("TEST.99994V", new string[] { "blabla" }); ExpectedResult = ErrorCodes.GetErrorInfo("TEST.99994V", "The code 'blabla' is no longer active.\r\nDo you still want to use it?"); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "ErrorCode without Attributes (ErrCodeCategory.NonCriticalError)"; TestResult = ErrorCodes.GetErrorInfo("TEST.99996N", new string[] { "test only" }); ExpectedResult = new ErrCodeInfo("TEST.99996N", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY4", String.Empty, String.Empty, "test only", String.Empty, ErrCodeCategory.NonCriticalError, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); Testname = "ErrorCode without Attributes (ErrCodeCategory.Error)"; TestResult = ErrorCodes.GetErrorInfo("TEST.99995x", new string[] { "test only" }); ExpectedResult = new ErrCodeInfo("TEST.99995x", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY5", String.Empty, String.Empty, "test only", String.Empty, ErrCodeCategory.Error, String.Empty); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "GetErrorInfo: " + Testname); ErrorCodeInventory.RegisteredTypes.Add(new TErrorCodesTest().GetType()); ErrorCodes.GetErrorInfo("TEST.88888V"); // The following test is needed to test-cover the if-branch in Method ErrorCodes.GetErrorInfo that performs a recursive Method call! TErrorCodesTest2.TestAddingOnTheFlyInUnregisteredClass(); #endregion #region This Test Case's Private Methods ('self-test') Testname = "EvaluateErrCodeInfoResults (identical values)"; TestResult = new ErrCodeInfo("TEST.99995x", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY5", "ShortDesc1", "FullDesc1", "ErrorMessageText1", "ErrorMessageTitleText1", ErrCodeCategory.Error, "HelpID1"); ExpectedResult = new ErrCodeInfo("TEST.99995x", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY5", "ShortDesc1", "FullDesc1", "ErrorMessageText1", "ErrorMessageTitleText1", ErrCodeCategory.Error, "HelpID1"); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsEmpty(VerificationProblemListing, "EvaluateErrCodeInfoResults: " + Testname); Testname = "EvaluateErrCodeInfoResults (non-identical values)"; TestResult = new ErrCodeInfo("TEST.99995x", "Ict.Common.Testing.TTestCommon", "ERR_TESTONLY5", "ShortDesc1", "FullDesc1", "ErrorMessageText1", "ErrorMessageTitleText1", ErrCodeCategory.Error, "HelpID1"); ExpectedResult = new ErrCodeInfo("TEST.99995x2", "Ict.Common.Testing.TTestCommon2", "ERR_TESTONLY52", "ShortDesc2", "FullDesc2", "ErrorMessageText2", "ErrorMessageTitleText2", ErrCodeCategory.NonCriticalError, "HelpID2"); VerificationProblemListing = EvaluateErrCodeInfoResults(ExpectedResult, TestResult); Assert.IsTrue(String.Compare( VerificationProblemListing, "AExpectedResult.Category != ATestResult.Category ('NonCriticalError' vs. 'Error'); " + "AExpectedResult.ErrorCode != ATestResult.ErrorCode ('TEST.99995x2' vs. 'TEST.99995x'); " + "AExpectedResult.ErrorCodeConstantClass != ATestResult.ErrorCodeConstantClass ('Ict.Common.Testing.TTestCommon2' vs. 'Ict.Common.Testing.TTestCommon'); " + "AExpectedResult.ErrorCodeConstantName != ATestResult.ErrorCodeConstantName ('ERR_TESTONLY52' vs. 'ERR_TESTONLY5'); " + "AExpectedResult.ErrorMessageText != ATestResult.ErrorMessageText ('ErrorMessageText2' vs. 'ErrorMessageText1'); " + "AExpectedResult.ErrorMessageTitle != ATestResult.ErrorMessageTitle ('ErrorMessageTitleText2' vs. 'ErrorMessageTitleText1'); " + "AExpectedResult.ShortDescription != ATestResult.ShortDescription ('ShortDesc2' vs. 'ShortDesc1'); " + "AExpectedResult.FullDescription != ATestResult.FullDescription ('FullDesc2' vs. 'FullDesc1'); " + "AExpectedResult.HelpID != ATestResult.HelpID ('HelpID2' vs. 'HelpID1')") == 0, "EvaluateErrCodeInfoResults: " + Testname); #endregion }
private string EvaluateErrCodeInfoResults(ErrCodeInfo AExpectedResult, ErrCodeInfo ATestResult) { StringCollection ErrCodeDifferences = new StringCollection(); string ReturnValue = String.Empty; if (AExpectedResult.Category != ATestResult.Category) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.Category != ATestResult.Category ('{0}' vs. '{1}')", AExpectedResult.Category, ATestResult.Category)); } if (AExpectedResult.ErrorCode != ATestResult.ErrorCode) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ErrorCode != ATestResult.ErrorCode ('{0}' vs. '{1}')", AExpectedResult.ErrorCode, ATestResult.ErrorCode)); } if (AExpectedResult.ErrorCodeConstantClass != ATestResult.ErrorCodeConstantClass) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ErrorCodeConstantClass != ATestResult.ErrorCodeConstantClass ('{0}' vs. '{1}')", AExpectedResult.ErrorCodeConstantClass, ATestResult.ErrorCodeConstantClass)); } if (AExpectedResult.ErrorCodeConstantName != ATestResult.ErrorCodeConstantName) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ErrorCodeConstantName != ATestResult.ErrorCodeConstantName ('{0}' vs. '{1}')", AExpectedResult.ErrorCodeConstantName, ATestResult.ErrorCodeConstantName)); } if (AExpectedResult.ErrorMessageText != ATestResult.ErrorMessageText) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ErrorMessageText != ATestResult.ErrorMessageText ('{0}' vs. '{1}')", AExpectedResult.ErrorMessageText, ATestResult.ErrorMessageText)); } if (AExpectedResult.ErrorMessageTitle != ATestResult.ErrorMessageTitle) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ErrorMessageTitle != ATestResult.ErrorMessageTitle ('{0}' vs. '{1}')", AExpectedResult.ErrorMessageTitle, ATestResult.ErrorMessageTitle)); } if (AExpectedResult.ShortDescription != ATestResult.ShortDescription) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.ShortDescription != ATestResult.ShortDescription ('{0}' vs. '{1}')", AExpectedResult.ShortDescription, ATestResult.ShortDescription)); } if (AExpectedResult.FullDescription != ATestResult.FullDescription) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.FullDescription != ATestResult.FullDescription ('{0}' vs. '{1}')", AExpectedResult.FullDescription, ATestResult.FullDescription)); } if (AExpectedResult.HelpID != ATestResult.HelpID) { ErrCodeDifferences.Add(String.Format( "AExpectedResult.HelpID != ATestResult.HelpID ('{0}' vs. '{1}')", AExpectedResult.HelpID, ATestResult.HelpID)); } if (ErrCodeDifferences.Count > 0) { foreach (string ErrCodeDiff in ErrCodeDifferences) { ReturnValue = ReturnValue + ErrCodeDiff + "; "; } // Strip off trailing "; " characters ReturnValue = ReturnValue.Substring(0, ReturnValue.Length - 2); } return ReturnValue; }
/// <summary> /// Populates the Dictionary <see cref="ErrorCodeCatalogue" /> from /// all public Constants of the Type that is passed in. /// </summary> /// <param name="AErrorCodesType">Type that contains public error Constants.</param> public static void BuildErrorCodeInventory(Type AErrorCodesType) { object[] ErrCodeAttributes; ErrCodeInfo ErrCodeDetails = null; ErrCodeCategory ErrCodeCat; string ErrCodeValue; //TLogging.Log("BuildErrorCodeInventory: AErrorCodesType Type: " + AErrorCodesType.Name); FieldInfo[] ErrcodesFields = AErrorCodesType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); try { for (int FieldCounter = 0; FieldCounter < ErrcodesFields.Length; FieldCounter++) { FieldInfo FieldInf = ErrcodesFields[FieldCounter]; ErrCodeDetails = null; // We are cataloging only public Constants! if ((!((FieldInf.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.InitOnly)) && ((FieldInf.Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public)) { // Constants' identifier (name) must start with "ERR_"! if (FieldInf.Name.StartsWith("ERR_")) { FieldInfo pi = AErrorCodesType.GetField(FieldInf.Name); ErrCodeAttributes = pi.GetCustomAttributes(typeof(ErrCodeAttribute), false); ErrCodeValue = FieldInf.GetValue(FieldInf).ToString(); if (ErrCodeValue.EndsWith("V")) { ErrCodeCat = ErrCodeCategory.Validation; } else if (ErrCodeValue.EndsWith("N")) { ErrCodeCat = ErrCodeCategory.NonCriticalError; } else { ErrCodeCat = ErrCodeCategory.Error; } if (ErrCodeAttributes.Length > 0) { foreach (ErrCodeAttribute Attr in ErrCodeAttributes) { ErrCodeDetails = new ErrCodeInfo(ErrCodeValue, AErrorCodesType.FullName, FieldInf.Name, Attr.ShortDescription, Attr.FullDescription, Attr.ErrorMessageText, Attr.ErrorMessageTitle, ErrCodeCat, Attr.HelpID, Attr.ControlValueUndoRequested); } } else { ErrCodeDetails = new ErrCodeInfo(ErrCodeValue, AErrorCodesType.FullName, FieldInf.Name, String.Empty, String.Empty, String.Empty, String.Empty, ErrCodeCat, String.Empty); } try { ErrorCodeCatalogue.Add(ErrCodeValue, ErrCodeDetails); } catch (ArgumentException) { ErrCodeInfo DefiningErrCodeInfo = ErrorCodes.GetErrorInfo(ErrCodeValue); throw new EDuplicateErrorCodeException( String.Format( "An attempt to add Error Code with value '{0}' through constant '{1}' failed, as there is already an Error Code with that value: it is defined through constant '{2}'.", ErrCodeValue, AErrorCodesType.FullName + "." + FieldInf.Name, DefiningErrCodeInfo.ErrorCodeConstantClass + "." + DefiningErrCodeInfo.ErrorCodeConstantName)); } } } } } finally { CataloguedTypes.Add(AErrorCodesType.Name, AErrorCodesType); //TLogging.Log("BuildErrorCodeInventory: Added " + AErrorCodesType.Name + " to the CataloguedTypes."); // System.Windows.Forms.MessageBox.Show("ErrorCodesInventory has " + ErrorCodeCatalogue.Count.ToString() + " Error Codes."); } }
/// <summary> /// Retrieves the <see cref="ErrCodeInfo" /> for a given Error Code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <returns><see cref="ErrCodeInfo" /> for the Error Code specified in <paramref name="AErrorCode" /> or /// null if the Error Code isn't found in any of the registered Types or in the calling Class.</returns> public static ErrCodeInfo RetrieveErrCodeInfo(string AErrorCode) { ErrCodeInfo ReturnValue = null; Type CheckedType = null; int Counter2 = 0; if (ErrorCodeCatalogue.ContainsKey(AErrorCode)) { ReturnValue = (ErrCodeInfo)ErrorCodeInventory.ErrorCodeCatalogue[AErrorCode]; } else { // Error Code wasn't found -> need to check whether it was registered and included in the Error Code Inventory! for (int Counter = 0; Counter < RegisteredTypes.Count; Counter++) { CheckedType = RegisteredTypes[Counter]; if (!AreTypesErrorCodesCatalogued(CheckedType.Name)) { BuildErrorCodeInventory(CheckedType); } if (ErrorCodeCatalogue.ContainsKey(AErrorCode)) { ReturnValue = (ErrCodeInfo)ErrorCodeInventory.ErrorCodeCatalogue[AErrorCode]; break; } } if (ReturnValue == null) { // 'On-the-fly' adding to the 'registered types' of the Type that called this Method. // This is needed for the case where an Error Code is defined in any Type other than the pre-registered Types. do { Counter2++; MethodBase method = new System.Diagnostics.StackTrace(false).GetFrame(Counter2).GetMethod(); if (method.DeclaringType.Name.StartsWith("<")) { // Note by AP: 17.08.2015 // This indicates that we were called by an anonymous delegate inside a method // - the Name property will be something like <>c as opposed to a sensible name // So we need to use the DeclaringType property twice // This is what happens in our TestErrorCodes Ict.Testing.lib.Common test // This seems to be a new feature that has come with a recent .NET update (?) or Visual Studio 2015 // because we never needed to do this before and tests always passed. CheckedType = method.DeclaringType.DeclaringType; } else { // Just a normal type CheckedType = method.DeclaringType; } } while (CheckedType.FullName == "Ict.Common.ErrorCodes"); if (!AreTypesErrorCodesCatalogued(CheckedType.Name)) { BuildErrorCodeInventory(CheckedType); // Recursive self-calling! ReturnValue = RetrieveErrCodeInfo(AErrorCode); } } } return(ReturnValue); }
/// <summary> /// Displays a MessageBox that shows a question and returns the users' choice. /// </summary> /// <param name="AErrCodeInfo">ErrCodeInfo which contains all the information.</param> /// <param name="ATypeWhichRaisesError">Instance of an object which raises the Error.</param> /// <param name="ADefaultToAnswerYes">Makes 'Yes' the button which is selected by default if true, /// otherwise 'No' is selected by default.</param> /// <returns>Users' choice.</returns> public static DialogResult MsgQuestion(ErrCodeInfo AErrCodeInfo, System.Type ATypeWhichRaisesError, bool ADefaultToAnswerYes) { return MsgQuestion(new TVerificationResult(ATypeWhichRaisesError, AErrCodeInfo), ATypeWhichRaisesError, ADefaultToAnswerYes); }
/// <summary> /// Returns an <see cref="ErrCodeInfo" /> object for a specified error code. /// </summary> /// <param name="AErrorCode">Error Code.</param> /// <param name="AErrorMessageText">Set this to <see cref="String.Empty" /> to use the /// <see cref="ErrCodeInfo.ShortDescription" /> of the <see cref="ErrCodeInfo" />, set it to any other string and /// this will be displayed instead.</param> /// <param name="AErrorMessagePlaceholderTexts">Array whose strings are placed into placeholders which are found in /// <paramref name="AErrorMessageText" /> (optional Argument!)</param>. /// <param name="AErrorTitlePlaceholderTexts">Array whose strings are placed into placeholders which are found in /// the ErrorCode's ErrorTitle (optional Argument!)</param>. /// /// <returns>An <see cref="ErrCodeInfo" /> object which holds information about /// the specified error code, or null, if the error code was not found.</returns> public static ErrCodeInfo GetErrorInfo(string AErrorCode, string AErrorMessageText, string[] AErrorMessagePlaceholderTexts = null, string[] AErrorTitlePlaceholderTexts = null) { ErrCodeInfo FoundErrInfo; ErrCodeInfo ReturnValue = null; string ErrorMessageText; string ErrorTitleText = String.Empty; if (AErrorMessageText == null) { throw new ArgumentException("Argument 'AErrorMessageText' must not be null"); } FoundErrInfo = GetErrorInfo(AErrorCode); if (AErrorMessageText == String.Empty) { if (FoundErrInfo.ErrorMessageText == String.Empty) { throw new ArgumentException( "Argument 'AErrorMessageText' must not be an empty string if the error code's ErrorMessageText is an empty string, too"); } else { ErrorMessageText = FoundErrInfo.ErrorMessageText; } } else { ErrorMessageText = AErrorMessageText; } if ((FoundErrInfo != null)) { if ((AErrorMessagePlaceholderTexts != null) && (AErrorMessagePlaceholderTexts.Length != 0)) { ErrorMessageText = String.Format(ErrorMessageText, AErrorMessagePlaceholderTexts); } ErrorTitleText = FoundErrInfo.ErrorMessageTitle; if ((AErrorTitlePlaceholderTexts != null) && (AErrorTitlePlaceholderTexts.Length != 0)) { ErrorTitleText = String.Format(ErrorTitleText, AErrorTitlePlaceholderTexts); } } ReturnValue = new ErrCodeInfo(FoundErrInfo.ErrorCode, FoundErrInfo.ErrorCodeConstantClass, FoundErrInfo.ErrorCodeConstantName, FoundErrInfo.ShortDescription, FoundErrInfo.FullDescription, ErrorMessageText, ErrorTitleText, FoundErrInfo.Category, FoundErrInfo.HelpID); return ReturnValue; }