diff --git a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs
index c8a9e0bd..94a9e564 100644
--- a/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs
+++ b/Examples/RTTI/RTTI_component/Bindings/CSharp/RTTI.cs
@@ -19,6 +19,126 @@ use of RTTI
namespace RTTI {
+ ///
+ /// Exception class for RTTI errors
+ ///
+ public class RTTIException : Exception
+ {
+ private readonly int _errorCode;
+ private readonly string _errorMessage;
+
+ ///
+ /// Initializes a new instance of the RTTIException class
+ ///
+ /// The error code
+ /// The error message
+ public RTTIException(int errorCode, string errorMessage = "") : base(FormatMessage(errorCode, errorMessage))
+ {
+ _errorCode = errorCode;
+ _errorMessage = errorMessage;
+ }
+
+ ///
+ /// Gets the error code
+ ///
+ public int ErrorCode => _errorCode;
+
+ ///
+ /// Gets the custom error message
+ ///
+ public string ErrorMessage => _errorMessage;
+
+ ///
+ /// Gets the error name (constant name)
+ ///
+ public string ErrorName
+ {
+ get
+ {
+ switch (_errorCode)
+ {
+ case 0: return "SUCCESS";
+ case 1: return "NOTIMPLEMENTED";
+ case 2: return "INVALIDPARAM";
+ case 3: return "INVALIDCAST";
+ case 4: return "BUFFERTOOSMALL";
+ case 5: return "GENERICEXCEPTION";
+ case 6: return "COULDNOTLOADLIBRARY";
+ case 7: return "COULDNOTFINDLIBRARYEXPORT";
+ case 8: return "INCOMPATIBLEBINARYVERSION";
+ default: return "UNKNOWN";
+ }
+ }
+ }
+
+ ///
+ /// Gets the error description (human-readable)
+ ///
+ public string ErrorDescription
+ {
+ get
+ {
+ switch (_errorCode)
+ {
+ case 0: return "success";
+ case 1: return "functionality not implemented";
+ case 2: return "an invalid parameter was passed";
+ case 3: return "a type cast failed";
+ case 4: return "a provided buffer is too small";
+ case 5: return "a generic exception occurred";
+ case 6: return "the library could not be loaded";
+ case 7: return "a required exported symbol could not be found in the library";
+ case 8: return "the version of the binary interface does not match the bindings interface";
+ default: return "unknown error";
+ }
+ }
+ }
+
+ private static string FormatMessage(int errorCode, string errorMessage)
+ {
+ string errorName = GetErrorName(errorCode);
+ string errorDesc = GetErrorDescription(errorCode);
+ if (!string.IsNullOrEmpty(errorMessage))
+ return $"RTTIException {errorName} ({errorCode}): {errorDesc} - {errorMessage}";
+ else
+ return $"RTTIException {errorName} ({errorCode}): {errorDesc}";
+ }
+
+ private static string GetErrorName(int errorCode)
+ {
+ switch (errorCode)
+ {
+ case 0: return "SUCCESS";
+ case 1: return "NOTIMPLEMENTED";
+ case 2: return "INVALIDPARAM";
+ case 3: return "INVALIDCAST";
+ case 4: return "BUFFERTOOSMALL";
+ case 5: return "GENERICEXCEPTION";
+ case 6: return "COULDNOTLOADLIBRARY";
+ case 7: return "COULDNOTFINDLIBRARYEXPORT";
+ case 8: return "INCOMPATIBLEBINARYVERSION";
+ default: return "UNKNOWN";
+ }
+ }
+
+ private static string GetErrorDescription(int errorCode)
+ {
+ switch (errorCode)
+ {
+ case 0: return "success";
+ case 1: return "functionality not implemented";
+ case 2: return "an invalid parameter was passed";
+ case 3: return "a type cast failed";
+ case 4: return "a provided buffer is too small";
+ case 5: return "a generic exception occurred";
+ case 6: return "the library could not be loaded";
+ case 7: return "a required exported symbol could not be found in the library";
+ case 8: return "the version of the binary interface does not match the bindings interface";
+ default: return "unknown error";
+ }
+ }
+ }
+
namespace Internal {
@@ -89,7 +209,7 @@ public static void ThrowError(IntPtr Handle, Int32 errorCode)
}
}
- throw new Exception(sMessage + "(# " + errorCode + ")");
+ throw new RTTIException(errorCode, sMessage);
}
/**
diff --git a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs
index 0d941855..f37d2bf8 100644
--- a/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs
+++ b/Examples/RTTI/RTTI_component/Examples/CSharp/RTTI_Example.cs
@@ -19,8 +19,68 @@ namespace RTTI_Example
{
class RTTI_Example
{
+ static void TestExceptionMethods()
+ {
+ Console.WriteLine("Testing RTTI Exception Methods...");
+
+ // Test by calling a method with invalid parameters to trigger an exception
+ try
+ {
+ // This should throw an ERTTIException with INVALIDPARAM error
+ // Manually throw an exception to test the exception properties
+ throw new RTTI.ERTTIException(2, "rtti exception");
+ }
+ catch (RTTI.ERTTIException ex)
+ {
+ Console.WriteLine("+ Successfully caught ERTTIException");
+
+ // Test the new exception properties
+ int errorCode = ex.ErrorCode;
+ string errorMessage = ex.ErrorMessage;
+ string errorName = ex.ErrorName;
+ string errorDescription = ex.ErrorDescription;
+ string baseMessage = ex.Message; // Base exception message from Exception class
+
+ Console.WriteLine($" Error Code: {errorCode}");
+ Console.WriteLine($" Error Message (custom): '{errorMessage}'");
+ Console.WriteLine($" Error Name: {errorName}");
+ Console.WriteLine($" Error Description: {errorDescription}");
+ Console.WriteLine($" Base Message: '{baseMessage}'");
+
+ // Verify error details - expecting INVALIDPARAM (code 2)
+ if (errorCode != 2)
+ throw new Exception($"Expected error code 2 (INVALIDPARAM), got {errorCode}");
+ if (errorName != "INVALIDPARAM")
+ throw new Exception($"Expected 'INVALIDPARAM', got '{errorName}'");
+ if (errorDescription != "an invalid parameter was passed")
+ throw new Exception($"Expected invalid parameter error description, got '{errorDescription}'");
+
+ // Test string representation
+ string exceptionStr = ex.ToString();
+ if (!exceptionStr.Contains("ERTTIException"))
+ throw new Exception($"String representation should contain 'ERTTIException', got '{exceptionStr}'");
+ if (!exceptionStr.Contains(errorCode.ToString()))
+ throw new Exception($"String representation should contain error code, got '{exceptionStr}'");
+
+ Console.WriteLine("+ All exception property tests passed!");
+ }
+ }
+
static void Main()
{
+ Console.WriteLine("RTTI C# Example with Exception Testing");
+ Console.WriteLine("==================================================");
+ Console.WriteLine();
+
+ // Test exception methods first
+ Console.WriteLine("Testing Exception Methods:");
+ Console.WriteLine("------------------------------");
+ TestExceptionMethods();
+ Console.WriteLine();
+
+ // Then run the main example
+ Console.WriteLine("Running Main RTTI Example:");
+ Console.WriteLine("------------------------------");
try
{
UInt32 nMajor, nMinor, nMicro;
@@ -96,9 +156,21 @@ static void Main()
if (!(Animal.GetHandle() != IntPtr.Zero)) throw new Exception("Wrong data");
if (!(Animal.Name().Equals("Gary Giraffe"))) throw new Exception("Wrong data");
if (!(Animal is RTTI.CGiraffe)) throw new Exception("Wrong data");
-
+
Animal = Iterator.GetNextAnimal();
if (!(Animal.GetHandle() == IntPtr.Zero)) throw new Exception("Wrong data");
+
+ Console.WriteLine("+ Main example completed successfully!");
+ }
+ catch (RTTI.ERTTIException ex)
+ {
+ Console.WriteLine("RTTI Exception occurred:");
+ Console.WriteLine($" Error Code: {ex.ErrorCode}");
+ Console.WriteLine($" Error Message: '{ex.ErrorMessage}'");
+ Console.WriteLine($" Error Name: {ex.ErrorName}");
+ Console.WriteLine($" Error Description: {ex.ErrorDescription}");
+ Console.WriteLine($" Full Exception: {ex}");
+ System.Environment.Exit(1);
}
catch (Exception e)
{
diff --git a/Source/buildbindingcsharp.go b/Source/buildbindingcsharp.go
index a0776339..13ed675d 100644
--- a/Source/buildbindingcsharp.go
+++ b/Source/buildbindingcsharp.go
@@ -650,6 +650,108 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW
w.Writeln("namespace %s {", NameSpace)
w.Writeln("")
+ // Generate custom exception class
+ w.Writeln(" /// ")
+ w.Writeln(" /// Exception class for %s errors", NameSpace)
+ w.Writeln(" /// ")
+ w.Writeln(" public class E%sException : Exception", NameSpace)
+ w.Writeln(" {")
+ w.Writeln(" private readonly int _errorCode;")
+ w.Writeln(" private readonly string _errorMessage;")
+ w.Writeln("")
+ w.Writeln(" /// ")
+ w.Writeln(" /// Initializes a new instance of the E%sException class", NameSpace)
+ w.Writeln(" /// ")
+ w.Writeln(" /// The error code")
+ w.Writeln(" /// The error message")
+ w.Writeln(" public E%sException(int errorCode, string errorMessage = \"\") : base(FormatMessage(errorCode, errorMessage))", NameSpace)
+ w.Writeln(" {")
+ w.Writeln(" _errorCode = errorCode;")
+ w.Writeln(" _errorMessage = errorMessage;")
+ w.Writeln(" }")
+ w.Writeln("")
+ w.Writeln(" /// ")
+ w.Writeln(" /// Gets the error code")
+ w.Writeln(" /// ")
+ w.Writeln(" public int ErrorCode => _errorCode;")
+ w.Writeln("")
+ w.Writeln(" /// ")
+ w.Writeln(" /// Gets the custom error message")
+ w.Writeln(" /// ")
+ w.Writeln(" public string ErrorMessage => _errorMessage;")
+ w.Writeln("")
+ w.Writeln(" /// ")
+ w.Writeln(" /// Gets the error name (constant name)")
+ w.Writeln(" /// ")
+ w.Writeln(" public string ErrorName")
+ w.Writeln(" {")
+ w.Writeln(" get")
+ w.Writeln(" {")
+ w.Writeln(" switch (_errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" case 0: return \"SUCCESS\";")
+ for _, errorDef := range component.Errors.Errors {
+ w.Writeln(" case %d: return \"%s\";", errorDef.Code, errorDef.Name)
+ }
+ w.Writeln(" default: return \"UNKNOWN\";")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln("")
+ w.Writeln(" /// ")
+ w.Writeln(" /// Gets the error description (human-readable)")
+ w.Writeln(" /// ")
+ w.Writeln(" public string ErrorDescription")
+ w.Writeln(" {")
+ w.Writeln(" get")
+ w.Writeln(" {")
+ w.Writeln(" switch (_errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" case 0: return \"success\";")
+ for _, errorDef := range component.Errors.Errors {
+ w.Writeln(" case %d: return \"%s\";", errorDef.Code, errorDef.Description)
+ }
+ w.Writeln(" default: return \"unknown error\";")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln("")
+ w.Writeln(" private static string FormatMessage(int errorCode, string errorMessage)")
+ w.Writeln(" {")
+ w.Writeln(" string errorName = GetErrorName(errorCode);")
+ w.Writeln(" string errorDesc = GetErrorDescription(errorCode);")
+ w.Writeln(" if (!string.IsNullOrEmpty(errorMessage))")
+ w.Writeln(" return $\"E%sException {errorName} ({errorCode}): {errorDesc} - {errorMessage}\";", NameSpace)
+ w.Writeln(" else")
+ w.Writeln(" return $\"E%sException {errorName} ({errorCode}): {errorDesc}\";", NameSpace)
+ w.Writeln(" }")
+ w.Writeln("")
+ w.Writeln(" private static string GetErrorName(int errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" switch (errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" case 0: return \"SUCCESS\";")
+ for _, errorDef := range component.Errors.Errors {
+ w.Writeln(" case %d: return \"%s\";", errorDef.Code, errorDef.Name)
+ }
+ w.Writeln(" default: return \"UNKNOWN\";")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln("")
+ w.Writeln(" private static string GetErrorDescription(int errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" switch (errorCode)")
+ w.Writeln(" {")
+ w.Writeln(" case 0: return \"success\";")
+ for _, errorDef := range component.Errors.Errors {
+ w.Writeln(" case %d: return \"%s\";", errorDef.Code, errorDef.Description)
+ }
+ w.Writeln(" default: return \"unknown error\";")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln(" }")
+ w.Writeln("")
+
for i := 0; i < len(component.Enums); i++ {
enum := component.Enums[i]
w.Writeln(" public enum e%s {", enum.Name)
@@ -967,7 +1069,7 @@ func buildBindingCSharpImplementation(component ComponentDefinition, w LanguageW
w.Writeln(" }")
w.Writeln("")
}
- w.Writeln(" throw new Exception(sMessage + \"(# \" + errorCode + \")\");")
+ w.Writeln(" throw new E%sException(errorCode, sMessage);", NameSpace)
w.Writeln(" }")
w.Writeln("")