Bug 17693 - Provide more detailed error message when NSData.ToString() fails for non-UTF-8 byte sequences?
Summary: Provide more detailed error message when NSData.ToString() fails for non-UTF-...
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 7.0.6.x
Hardware: PC Mac OS
: --- enhancement
Target Milestone: 7.2.1
Assignee: Bugzilla
Depends on:
Reported: 2014-02-10 19:32 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2014-03-20 13:54 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Test case (7.72 KB, application/zip)
2014-02-10 19:32 UTC, Brendan Zagaeski (Xamarin Team, assistant)

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Brendan Zagaeski (Xamarin Team, assistant) 2014-02-10 19:32:09 UTC
Created attachment 6019 [details]
Test case

## Steps to reproduce

Build and run the attached test case.

## Result

System.Exception: Could not initialize an instance of the type 'MonoTouch.Foundation.NSString': the native 'initWithData:encoding:' method returned nil.
It is possible to ignore this condition by setting MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure to false.

## Possible improvement

The problem in this project is that the `bytes` array cannot be converted to a string using the UTF-8 encoding. The resulting error is correct, but it's a little confusing. Perhaps a more instructive error message could be provided for the specific case of `[NSString initWithData:encoding:]`? For example, perhaps the error message could include something like:
> "Make sure that the input byte stream is compatible with the encoding: {0}.", encoding.ToString()

These errors that get thrown when `init` methods return `nil` are a new feature [1], so I suspect there might already be some plans to provide more detailed error messages in future versions.

> [1] http://forums.xamarin.com/discussion/12880/app-crash-after-xamarin-ios-update-system-exception

Comment 2 Sebastien Pouliot 2014-02-10 22:16:16 UTC
> These errors that get thrown when `init` methods return `nil` are a new feature

Not quite. In the past an "invalid" (handle = nil) instance was created and would fail later whenever it was used. That "delayed" failure make it hard to track and fix such issues.

What's new is that we now report the error when it occurs (at initialization time) instead of later.

> so I suspect there might already be some plans to provide more detailed...

No. That check is not a in good place for customization. Also there must be over a thousand iOS/OSX `init*` selectors that can all return `nil` under certain, 90%+ undocumented, circumstances (and each specific error message would require extra space in the final application).

Even Apple behavior is erratic in such cases - most often it return `nil` silently (something that a .NET ctor cannot do), some time it logs (NSLog) an message and in a few cases it abort/crash.

What we could do is point to a FAQ that list the most common* / known cases (and update that web page when a new case is detected by dev, qa or support) and modify the current error message to point to the URL.

* the most common one I've seen is with NSUrl where an invalid URL returns `nil` and what's valid varies by iOS versions.

Side note: Those (both the encoding and URL) are good cases where using the equivalent .NET API would solve the issue (and a major reason why some native API were not, and still are not, bound). Using the .NET API would:

* provide much better error/exception messages;

* solve issues when some selectors are only available in more recent version of iOS (e.g. the base64 selectors are quite recent in iOS but available in all versions of XI);

* be more consistant across devices (e.g. the NSUrl validation wrt iOS versions); and

* make the application code more portable :-)
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2014-02-11 11:47:19 UTC
Excellent explanation of the complications here. Thanks! A FAQ for common causes sounds good.
Comment 4 Brendan Zagaeski (Xamarin Team, assistant) 2014-02-11 12:07:06 UTC
A slightly different question: for the specific case of `NSData.ToString()`, would it make any sense to provide an additional "backup" conversion in case converting to a UTF-8 string fails? For example, maybe `NSData.ToString()` could return a string of "0xNN" byte values if the UTF-8 conversion fails?
Comment 5 Sebastien Pouliot 2014-02-12 15:55:58 UTC
Indeed! I missed that bit from the title. From [1]:

* Your ToString override should not throw an exception.

[1] http://msdn.microsoft.com/en-us/library/system.object.tostring(v=vs.110).aspx
Comment 6 Sebastien Pouliot 2014-02-23 11:19:11 UTC
NSData.ToString fixed in master / e3ba8d0eeeb7729a5f73dd904db420b92df57574

QA: unit tests added in the same commit

If you create a support FAQ about this then let me know the URL and I'll update the error message to point to it.
Comment 7 Ram Chandra 2014-03-20 13:54:31 UTC
I have checked this issue on following builds:

Mac 10.7.5
Xamarin Studio : 4.2.4 (build 32)
Xamarin.iOS : (Trial Edition)
Build Information
Release ID: 402040032
Git revision: a160c35dac9ab9fd32eeadaa171216316d5a5133
Build date: 2014-03-12 13:55:08-04
Xamarin addins: a779416ceabd54981ce812771a4061c942e8b872

I have checked  the signature of override "ToString()" method of  in "assembly browser" and I observed that the signature of override "ToString()" is updated in latest build (xamarin.iOS I have also observed that when I hover on the "x" variable in the line no33 i.e. "var x = NSData.FromArray(bytes);" it does not show exception message instead it shows the values of byte array but in stable it shows the exception message when we hover cursor over the variable "x".

screencast:  http://www.screencast.com/t/VzCcoS8f

This issue is working fine. Hence, I am closing this issue.

Please let me know if I am missing anything.