diff --git a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py index 361e0e13..fba4827f 100644 --- a/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py +++ b/Examples/RTTI/RTTI_component/Bindings/Python/RTTI.py @@ -32,6 +32,80 @@ def __str__(self): if self._message: return 'RTTIException ' + str(self._code) + ': '+ str(self._message) return 'RTTIException ' + str(self._code) + + def get_error_code(self): + """Returns the error code""" + return self._code + + def get_error_message(self): + """Returns the custom error message""" + return self._message + + def get_error_name(self): + """Returns the error name (constant name)""" + if self._code == ErrorCodes.SUCCESS: + return 'SUCCESS' + elif self._code == ErrorCodes.NOTIMPLEMENTED: + return 'NOTIMPLEMENTED' + elif self._code == ErrorCodes.INVALIDPARAM: + return 'INVALIDPARAM' + elif self._code == ErrorCodes.INVALIDCAST: + return 'INVALIDCAST' + elif self._code == ErrorCodes.BUFFERTOOSMALL: + return 'BUFFERTOOSMALL' + elif self._code == ErrorCodes.GENERICEXCEPTION: + return 'GENERICEXCEPTION' + elif self._code == ErrorCodes.COULDNOTLOADLIBRARY: + return 'COULDNOTLOADLIBRARY' + elif self._code == ErrorCodes.COULDNOTFINDLIBRARYEXPORT: + return 'COULDNOTFINDLIBRARYEXPORT' + elif self._code == ErrorCodes.INCOMPATIBLEBINARYVERSION: + return 'INCOMPATIBLEBINARYVERSION' + else: + return 'UNKNOWN' + + def get_error_description(self): + """Returns the error description (human-readable)""" + if self._code == ErrorCodes.SUCCESS: + return 'success' + elif self._code == ErrorCodes.NOTIMPLEMENTED: + return 'functionality not implemented' + elif self._code == ErrorCodes.INVALIDPARAM: + return 'an invalid parameter was passed' + elif self._code == ErrorCodes.INVALIDCAST: + return 'a type cast failed' + elif self._code == ErrorCodes.BUFFERTOOSMALL: + return 'a provided buffer is too small' + elif self._code == ErrorCodes.GENERICEXCEPTION: + return 'a generic exception occurred' + elif self._code == ErrorCodes.COULDNOTLOADLIBRARY: + return 'the library could not be loaded' + elif self._code == ErrorCodes.COULDNOTFINDLIBRARYEXPORT: + return 'a required exported symbol could not be found in the library' + elif self._code == ErrorCodes.INCOMPATIBLEBINARYVERSION: + return 'the version of the binary interface does not match the bindings interface' + else: + return 'unknown error' + + @property + def error_code(self): + """Property to access error code""" + return self._code + + @property + def error_message(self): + """Property to access custom error message""" + return self._message + + @property + def error_name(self): + """Property to access error name""" + return self.get_error_name() + + @property + def error_description(self): + """Property to access error description""" + return self.get_error_description() '''Definition of binding API version ''' diff --git a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py index 98ebaabf..55b39fee 100644 --- a/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py +++ b/Examples/RTTI/RTTI_component/Examples/Python/RTTI_Example.py @@ -20,6 +20,43 @@ import RTTI +def test_exception_methods(): + """Test the new exception methods using assert statements""" + print("Testing RTTI Exception Methods...") + + # Test with a non-existent library to trigger an exception + try: + wrapper = RTTI.Wrapper(libraryName="nonexistent_library") + assert False, "Should have thrown an exception!" + except RTTI.ERTTIException as e: + print("+ Successfully caught ERTTIException") + + # Test the new methods with assertions + error_code = e.get_error_code() + error_message = e.get_error_message() + error_name = e.get_error_name() + error_description = e.get_error_description() + + # Assertions for method functionality + assert error_code == RTTI.ErrorCodes.COULDNOTLOADLIBRARY, f"Expected error code 6, got {error_code}" + assert error_name == "COULDNOTLOADLIBRARY", f"Expected 'COULDNOTLOADLIBRARY', got '{error_name}'" + assert error_description == "the library could not be loaded", f"Expected library load error description, got '{error_description}'" + assert "nonexistent_library" in error_message, f"Expected library name in message, got '{error_message}'" + + # Test properties (alternative access) + assert e.error_code == error_code, "Property error_code should match method get_error_code()" + assert e.error_message == error_message, "Property error_message should match method get_error_message()" + assert e.error_name == error_name, "Property error_name should match method get_error_name()" + assert e.error_description == error_description, "Property error_description should match method get_error_description()" + + # Test string representation + exception_str = str(e) + assert "RTTIException" in exception_str, f"String representation should contain 'RTTIException', got '{exception_str}'" + assert str(error_code) in exception_str, f"String representation should contain error code, got '{exception_str}'" + + print("+ All exception method tests passed!") + + def main(): libpath = '' # TODO add the location of the shared library binary here wrapper = RTTI.Wrapper(libraryName = os.path.join(libpath, "rtti")) @@ -96,7 +133,21 @@ def main(): animal = iter.GetNextAnimal(); assert not animal if __name__ == "__main__": + # Test exception methods first (before main, as it uses a non-existent library) + print("Testing Exception Methods:") + print("-" * 30) + test_exception_methods() + print() + + # Then run the main example + print("Running Main RTTI Example:") + print("-" * 30) try: main() except RTTI.ERTTIException as e: - print(e) + print("RTTI Exception occurred:") + print(f" Error Code: {e.get_error_code()}") + print(f" Error Message: '{e.get_error_message()}'") + print(f" Error Name: {e.get_error_name()}") + print(f" Error Description: {e.get_error_description()}") + print(f" Full Exception: {e}") diff --git a/Source/buildbindingpython.go b/Source/buildbindingpython.go index a96d4da2..31d36cf2 100644 --- a/Source/buildbindingpython.go +++ b/Source/buildbindingpython.go @@ -132,6 +132,56 @@ func buildDynamicPythonImplementation(componentdefinition ComponentDefinition, w w.Writeln(" if self._message:") w.Writeln(" return '%sException ' + str(self._code) + ': '+ str(self._message)", NameSpace) w.Writeln(" return '%sException ' + str(self._code)", NameSpace) + w.Writeln(" ") + w.Writeln(" def get_error_code(self):") + w.Writeln(" \"\"\"Returns the error code\"\"\"") + w.Writeln(" return self._code") + w.Writeln(" ") + w.Writeln(" def get_error_message(self):") + w.Writeln(" \"\"\"Returns the custom error message\"\"\"") + w.Writeln(" return self._message") + w.Writeln(" ") + w.Writeln(" def get_error_name(self):") + w.Writeln(" \"\"\"Returns the error name (constant name)\"\"\"") + w.Writeln(" if self._code == ErrorCodes.SUCCESS:") + w.Writeln(" return 'SUCCESS'") + for _, errorDef := range componentdefinition.Errors.Errors { + w.Writeln(" elif self._code == ErrorCodes.%s:", errorDef.Name) + w.Writeln(" return '%s'", errorDef.Name) + } + w.Writeln(" else:") + w.Writeln(" return 'UNKNOWN'") + w.Writeln(" ") + w.Writeln(" def get_error_description(self):") + w.Writeln(" \"\"\"Returns the error description (human-readable)\"\"\"") + w.Writeln(" if self._code == ErrorCodes.SUCCESS:") + w.Writeln(" return 'success'") + for _, errorDef := range componentdefinition.Errors.Errors { + w.Writeln(" elif self._code == ErrorCodes.%s:", errorDef.Name) + w.Writeln(" return '%s'", errorDef.Description) + } + w.Writeln(" else:") + w.Writeln(" return 'unknown error'") + w.Writeln(" ") + w.Writeln(" @property") + w.Writeln(" def error_code(self):") + w.Writeln(" \"\"\"Property to access error code\"\"\"") + w.Writeln(" return self._code") + w.Writeln(" ") + w.Writeln(" @property") + w.Writeln(" def error_message(self):") + w.Writeln(" \"\"\"Property to access custom error message\"\"\"") + w.Writeln(" return self._message") + w.Writeln(" ") + w.Writeln(" @property") + w.Writeln(" def error_name(self):") + w.Writeln(" \"\"\"Property to access error name\"\"\"") + w.Writeln(" return self.get_error_name()") + w.Writeln(" ") + w.Writeln(" @property") + w.Writeln(" def error_description(self):") + w.Writeln(" \"\"\"Property to access error description\"\"\"") + w.Writeln(" return self.get_error_description()") w.Writeln("")