[runtime] Use the full managed description (including inner exceptions) as the reason when creating an NSException from a managed exception. (#14002)

This makes diagnosing what happens much easier in some cases.

Exhibit A, pre fix:

    *** Terminating app due to uncaught exception 'ObjCRuntime.RuntimeException', reason: 'Failed to lookup the required marshalling information.
    Additional information:
    	Selector: conformsToProtocol:
    	Type: ViewController

Exhibit B, post fix:

    *** Terminating app due to uncaught exception 'ObjCRuntime.RuntimeException', reason: 'Failed to lookup the required marshalling information.
    Additional information:
    	Selector: conformsToProtocol:
    	Type: ViewController
     (ObjCRuntime.RuntimeException)
    Failed to get the 'this' instance in a method call to templ.ViewController.InvokeConformsToProtocol. (ObjCRuntime.RuntimeException)
       at Registrar.DynamicRegistrar.GetMethodDescriptionAndObject(Type type, IntPtr selector, Boolean is_static, IntPtr obj, IntPtr& mthis, IntPtr desc)
       at ObjCRuntime.Runtime.GetMethodAndObjectForSelector(IntPtr klass, IntPtr sel, Boolean is_static, IntPtr obj, IntPtr& mthis, IntPtr desc)
       at ObjCRuntime.Runtime.get_method_and_object_for_selector(IntPtr cls, IntPtr sel, Boolean is_static, IntPtr obj, IntPtr& mthis, IntPtr desc, IntPtr& exception_gchandle)
    Failed to marshal the Objective-C object 0x7f813fd2f470 (type: ViewController). Could not find an existing managed instance for this object, nor was it possible to create a new managed instance (because the type 'templ.ViewController' does not have a constructor that takes one NativeHandle argument). (ObjCRuntime.RuntimeException)
       at ObjCRuntime.Runtime.MissingCtor(IntPtr ptr, IntPtr klass, Type type, MissingCtorResolution resolution)
       at ObjCRuntime.Runtime.ConstructNSObject[T](IntPtr ptr, Type type, MissingCtorResolution missingCtorResolution)
       at ObjCRuntime.Runtime.ConstructNSObject(IntPtr ptr, IntPtr klass, MissingCtorResolution missingCtorResolution)
       at ObjCRuntime.Runtime.GetNSObject(IntPtr ptr, MissingCtorResolution missingCtorResolution, Boolean evenInFinalizerQueue)
       at Registrar.DynamicRegistrar.GetMethodDescriptionAndObject(Type type, IntPtr selector, Boolean is_static, IntPtr obj, IntPtr& mthis, IntPtr desc)
This commit is contained in:
Rolf Bjarne Kvinge 2022-02-02 16:22:34 +01:00 коммит произвёл GitHub
Родитель 9842974c0d
Коммит d5697a8867
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 5 добавлений и 8 удалений

Просмотреть файл

@ -2366,16 +2366,13 @@ xamarin_process_managed_exception (MonoObject *exception)
xamarin_free (fullname);
}
char *message = xamarin_get_exception_message (handle, &exception_gchandle);
reason = xamarin_print_all_exceptions (handle);
if (exception_gchandle != INVALID_GCHANDLE) {
PRINT (PRODUCT ": Got an exception when trying to get the message for an exception (this exception will be ignored):");
PRINT ("%@", xamarin_print_all_exceptions (exception_gchandle));
xamarin_gchandle_free (exception_gchandle);
exception_gchandle = INVALID_GCHANDLE;
reason = @"Unknown message";
} else {
reason = [NSString stringWithUTF8String: message];
xamarin_free (message);
}
userInfo = [NSDictionary dictionaryWithObject: [XamarinGCHandle createWithHandle: handle] forKey: @"XamarinManagedExceptionHandle"];

Просмотреть файл

@ -154,7 +154,7 @@ namespace MonoTouchFixtures.ObjCRuntime {
thrownException = ex;
}
Assert.AreSame (e.Exception, thrownException, "exception");
Assert.AreEqual ("3,14", thrownException.Message, "1 thrown message");
Assert.That (thrownException.Message, Does.StartWith ("3,14"), "1 thrown message");
Assert.AreSame (typeof (ApplicationException), thrownException.GetType (), "1 thrown type");
if (hasDebugger) {
Assert.AreEqual (0, objcEventArgs.Count, "1 objc exception");
@ -162,7 +162,7 @@ namespace MonoTouchFixtures.ObjCRuntime {
Assert.AreEqual (1, objcEventArgs.Count, "1 objc exception");
Assert.AreEqual (defaultObjectiveCExceptionMode, objcEventArgs [0].ExceptionMode, "1 objc mode");
Assert.AreEqual ("System.ApplicationException", objcEventArgs [0].Exception.Name, "1 objc reason");
Assert.AreEqual ("3,14", objcEventArgs [0].Exception.Reason, "1 objc message");
Assert.That (objcEventArgs [0].Exception.Reason, Does.StartWith ("3,14"), "1 objc message");
}
if (hasDebugger) {
Assert.AreEqual (0, managedEventArgs.Count, "1 managed count");
@ -187,7 +187,7 @@ namespace MonoTouchFixtures.ObjCRuntime {
Assert.AreNotSame (e.Exception, thrownException, "exception");
Assert.AreSame (typeof (ObjCException), thrownException.GetType (), "2 thrown type");
Assert.AreEqual ("Caught exception", ((ObjCException) thrownException).Name, "2 thrown name");
Assert.AreEqual ("exception was rethrown", ((ObjCException) thrownException).Reason, "2 thrown reason");
Assert.That (((ObjCException) thrownException).Reason, Does.StartWith ("exception was rethrown") , "2 thrown reason");
}
if (hasDebugger) {
Assert.AreEqual (0, objcEventArgs.Count, "2 objc exception");
@ -195,7 +195,7 @@ namespace MonoTouchFixtures.ObjCRuntime {
Assert.AreEqual (1, objcEventArgs.Count, "2 objc exception");
Assert.AreEqual (defaultObjectiveCExceptionMode, objcEventArgs [0].ExceptionMode, "2 objc mode");
Assert.AreEqual ("Caught exception", objcEventArgs [0].Exception.Name, "2 objc reason");
Assert.AreEqual ("exception was rethrown", objcEventArgs [0].Exception.Reason, "2 objc message");
Assert.That (objcEventArgs [0].Exception.Reason, Does.StartWith ("exception was rethrown"), "2 objc message");
}
if (hasDebugger) {
Assert.AreEqual (0, managedEventArgs.Count, "2 managed count");