Skip to content

[generator] Gracefully handle BindingGeneratorException. #845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 26, 2021

Conversation

jpobst
Copy link
Contributor

@jpobst jpobst commented May 20, 2021

Mel pointed out that if you have invalid XPath in your metadata, we simply error with the unhelpful "generator.exe" exited with code -XXXXXX:

before

If you turn on Diagnostic logs, you can see the uncaught exception hiding in a lot of ceremony:

  Unhandled Exception: Java.Interop.Tools.Generator.BindingGeneratorException: C:\code\temp\xamarin.exoplayer\Xamarin.ExoPlayer.Core\Transforms\Metadata.xml(11, 4): error BG4304: Invalid XPath specification: /api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2]. ---> System.Xml.XPath.XPathException: '/api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2]' has an invalid token. (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000: Unhandled Exception: Java.Interop.Tools.Generator.BindingGeneratorException: C:\code\temp\xamarin.exoplayer\Xamarin.ExoPlayer.Core\Transforms\Metadata.xml(11, 4): error BG4304: Invalid XPath specification: /api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2]. ---> System.Xml.XPath.XPathException: '/api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2]' has an invalid token. (TaskId:46)
     at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion) (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion) (TaskId:46)
     at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver) (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver) (TaskId:46)
     at System.Xml.XPath.XPathNavigator.Evaluate(String xpath, IXmlNamespaceResolver resolver) (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at System.Xml.XPath.XPathNavigator.Evaluate(String xpath, IXmlNamespaceResolver resolver) (TaskId:46)
     at System.Xml.XPath.XPathEvaluator.Evaluate[T](XNode node, String expression, IXmlNamespaceResolver resolver) (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at System.Xml.XPath.XPathEvaluator.Evaluate[T](XNode node, String expression, IXmlNamespaceResolver resolver) (TaskId:46)
     at System.Xml.XPath.Extensions.XPathSelectElements(XNode node, String expression, IXmlNamespaceResolver resolver) (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at System.Xml.XPath.Extensions.XPathSelectElements(XNode node, String expression, IXmlNamespaceResolver resolver) (TaskId:46)
     at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs:line 110 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs:line 110 (TaskId:46)
     --- End of inner exception stack trace --- (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    --- End of inner exception stack trace --- (TaskId:46)
     at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, String sourceFile, Int32 line, Int32 column, String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/Report.cs:line 88 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, String sourceFile, Int32 line, Int32 column, String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/Report.cs:line 88 (TaskId:46)
     at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, XNode node, String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/Report.cs:line 81 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, XNode node, String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/Report.cs:line 81 (TaskId:46)
     at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs:line 124 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs:line 124 (TaskId:46)
     at Java.Interop.Tools.Generator.ApiXmlDocument.ApplyFixupFile(FixupXmlDocument fixup) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs:line 40 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Java.Interop.Tools.Generator.ApiXmlDocument.ApplyFixupFile(FixupXmlDocument fixup) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs:line 40 (TaskId:46)
     at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options, DirectoryAssemblyResolver resolver) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 150 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options, DirectoryAssemblyResolver resolver) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 150 (TaskId:46)
     at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 39 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 39 (TaskId:46)
     at Xamarin.Android.Binder.CodeGenerator.Main(String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 30 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Main(String[] args) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/tools/generator/CodeGenerator.cs:line 30 (TaskId:46)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(53,5): error MSB6006: "generator.exe" exited with code -532462766.

It turns out this happens anywhere we throw a BindingGeneratorException as there is no catch handler that attempts to gracefully handles this exception. This led to making several improvements:

  • Gracefully handle BindingGeneratorException such that we print out the error as a standard MSBuild error that can be processed by Visual Studio.
  • Exit generator with -1 if BindingGeneratorException is thrown.
  • Add a separate Report.LogCodedError (...) method called Report.LogCodeErrorAndExit (...) which is used for terminal errors ("don't do any further processing and exit").
  • Audit existing calls to Report.LogCodedError (...) to allow errors such as Invalid XPath to be non-terminal. (Today generator will exit after finding the first one.)
  • Remove spaces in the error file location: metadata.xml(8, 4): -> metadata.xml(8,4):. These were not being processed correctly and could not be double clicked in VS previously.

Results:
after

We additionally handle any unhandled exception a little better:
unhandled

Additionally ApiFixup.cs was deleted as it was no longer used after the refactor in commit f4e68b5.

@jpobst jpobst force-pushed the generator-errors branch from af821d4 to 6f2ca1c Compare May 20, 2021 19:03
@jpobst jpobst marked this pull request as ready for review May 20, 2021 19:14
Run (options);
} catch (BindingGeneratorException) {
return 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should other exception types be handled, "just in case", so that we don't get the "unhandled exception" output? Or do we want the unhandled exception output?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, added.

@jonpryor
Copy link
Contributor

I'm feeling like a dummy reviewing this, but:

How are BindingGeneratorException exception messages printed out? Report.LogCodedErrorAndExit() just throws a new BindingGeneratorException -- calling Report.Format() as a side effect -- but I don't see how that ever gets written to Console.Out or Console.Error.

I also find it to be a "nicer experience" if "as many errors as possible" can be printed, vs. just bailing at the first error, and I fear that Report.LogCodedErrorAndExit() will mean that we don't get "as many errors" found or encountered. This might just be my over-thinking things.

// BG4301
Report.LogCodedError (Report.ErrorRemoveNodeInvalidXPath, e, metaitem, path);
Report.LogCodedError (Report.ErrorRemoveNodeInvalidXPath, metaitem, path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we want to include e anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use it anywhere, we simply print out the localized message.

@jpobst
Copy link
Contributor Author

jpobst commented May 25, 2021

Report.LogCodedErrorAndExit() calls Report.LogCodedError() which outputs the error message to Console.Error. BindingGeneratorException no longer does anything with the message it is given, it simply acts as an exception that has already been handled and thus our catch knows just to exit generator.

I made most errors non-terminal so that we'll output them all. The remaining terminal ones are largely various "this shouldn't happen" errors that we probably can't recover from.

@jonpryor jonpryor merged commit 0227cda into main May 26, 2021
@jonpryor jonpryor deleted the generator-errors branch May 26, 2021 22:40
jonpryor pushed a commit that referenced this pull request Jun 15, 2021
@moljac pointed out that if you have invalid XPath in your metadata,
we simply error with the unhelpful:

	"generator.exe" exited with code -XXXXXX

![before](https://user-images.githubusercontent.com/179295/119032575-f4891680-b971-11eb-9580-96cc2e96e4aa.png)

If you turn on `Diagnostic` logs, you can see the uncaught exception
hiding in a lot of ceremony:

	message BG0000: Unhandled Exception: Java.Interop.Tools.Generator.BindingGeneratorException:
	  C:\code\temp\xamarin.exoplayer\Xamarin.ExoPlayer.Core\Transforms\Metadata.xml(11, 4):
	  error BG4304: Invalid XPath specification: /api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2].
	  ---> System.Xml.XPath.XPathException: '/api/package[@name='com.google.android.exoplayer2']interface[@name='ExoPlayer']/method[@name='addMediaItems' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.util.List<com.google.android.exoplayer2.source.MediaSource>']]/parameter[2]' has an invalid token.
	message BG0000:    at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion)
	message BG0000:    at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver)
	message BG0000:    at System.Xml.XPath.XPathNavigator.Evaluate(String xpath, IXmlNamespaceResolver resolver)
	message BG0000:    at System.Xml.XPath.XPathEvaluator.Evaluate[T](XNode node, String expression, IXmlNamespaceResolver resolver)
	message BG0000:    at System.Xml.XPath.Extensions.XPathSelectElements(XNode node, String expression, IXmlNamespaceResolver resolver)
	message BG0000:    at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion)
	message BG0000:    --- End of inner exception stack trace --- (TaskId:46)
	message BG0000:    at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, String sourceFile, Int32 line, Int32 column, String[] args)
	message BG0000:    at Java.Interop.Tools.Generator.Report.LogCodedError(LocalizedMessage message, Exception innerException, XNode node, String[] args)
	message BG0000:    at Java.Interop.Tools.Generator.FixupXmlDocument.Apply(ApiXmlDocument apiDocument, String apiLevelString, Int32 productVersion)
	message BG0000:    at Java.Interop.Tools.Generator.ApiXmlDocument.ApplyFixupFile(FixupXmlDocument fixup)
	message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options, DirectoryAssemblyResolver resolver)
	message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Run(CodeGeneratorOptions options)
	message BG0000:    at Xamarin.Android.Binder.CodeGenerator.Main(String[] args)
	error MSB6006: "generator.exe" exited with code -532462766.


It turns out this happens anywhere we throw a
`BindingGeneratorException`, as there is no `catch` handler that
attempts to gracefully handles this exception.

This led to making several improvements:

  - Gracefully handle `BindingGeneratorException` such that we print
    out the error as a standard MSBuild error that can be processed
    by Visual Studio.

  - Exit `generator` with `-1` if `BindingGeneratorException` is thrown.

  - Add a separate `Report.LogCodedError(…)` method called
    `Report.LogCodeErrorAndExit(…)`, which is used for terminal errors
    ("don't do any further processing and exit").

  - Audit existing calls to `Report.LogCodedError()` to allow errors
    such as `Invalid XPath` to be non-terminal.
    (Today `generator` will exit after finding the first one.)

  - Remove spaces in the error file location: `metadata.xml(8, 4): `
    becomes `metadata.xml(8,4):`.
    
    These were not being processed correctly and could not be double
    clicked in VS previously.

The result is a more useful error message:

	Metadata.xml(11,4): error BG4304: Invalid XPath specification …

We also now handle any unhandled exception a little better.

Additionally, `ApiFixup.cs` was deleted as it was no longer used after
the refactor in commit f4e68b5.
@jpobst jpobst added this to the 11.4 (16.11 / 8.11) milestone Jul 6, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Apr 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants