Skip to content

Exceptions can be swallowed with no actionable output #1726

@jonpryor

Description

@jonpryor

(All the interesting bugs are under NativeAOT!)

Build and run Uno.Chefs for macOS desktop under NativeAOT, which in turn requires using Uno.Sdk 6.6.0:

sed -i '' 's/"Uno.Sdk": ".*"/"Uno.Sdk": "6.6.0-dev.3"/g' global.json
dotnet publish -c Release -r osx-x64 -f net10.0-desktop -p:TargetFrameworkOverride=net10.0-desktop \
  -bl Chefs/Chefs.csproj -p:UseSkiaRendering=true -p:SkiaPublishAot=true \
  -p:SkiaPublishAot=true \
  -p:IlcGenerateMapFile=true -p:IlcGenerateMstatFile=true -p:IlcGenerateDgmlFile=true -p:IlcGenerateMetadataLog=true \
  -p:EmitCompilerGeneratedFiles=true -p:CompilerGeneratedFilesOutputPath=`pwd`/_gen
Chefs/bin/Release/net10.0-desktop/osx-x64/publish/Chefs

From the launch screen:

  1. Click Skip
  2. Click  Sign in with Apple
  3. Click 🔍Search on the left
  4. In the Search box, type m

Current behavior

The search results screen shows:

An error occurred.

Image

The console log shows nothing.

The lack of any information about the error that occurred makes it difficult to fix the bug.

Desired behavior

The console log should show the exception that was thrown.

Implementation

For all classes underneath the Chefs.Business.Services namespace, including:

  • Chefs/Business/Services/Sharing/ShareService.cs
  • Chefs/Business/Services/Recipes/RecipeService.cs
  • Chefs/Business/Services/Users/UserService.cs
  • Chefs/Business/Services/Cookbooks/CookbookService.cs
  • Chefs/Business/Services/Notifications/NotificationService.cs

Perform the following changes:

  1. Add an ILogger<T> logger constructor parameter, in which T is the declaring type:

    diff --git a/Chefs/Business/Services/Sharing/ShareService.cs b/Chefs/Business/Services/Sharing/ShareService.cs
    index ec38f458..0e5a6e07 100644
    --- a/Chefs/Business/Services/Sharing/ShareService.cs
    +++ b/Chefs/Business/Services/Sharing/ShareService.cs
    @@ -6,7 +6,7 @@ using WinRT.Interop;
     
     namespace Chefs.Business.Services.Sharing;
     
    -public class ShareService() : IShareService
    +public class ShareService(ILogger<ShareService> logger) : IShareService
     {
            private Recipe? _recipe;
            private IImmutableList<Step>? _steps;
  2. For each public method which returns Task, Task<T>, ValueTask, or ValueTask<T>, rename the method by appending a Core suffix, and change the visibility to private:

    diff --git a/Chefs/Business/Services/Sharing/ShareService.cs b/Chefs/Business/Services/Sharing/ShareService.cs
    index ec38f458..fb82cef4 100644
    --- a/Chefs/Business/Services/Sharing/ShareService.cs
    +++ b/Chefs/Business/Services/Sharing/ShareService.cs
    @@ -16,7 +16,7 @@ public class ShareService() : IShareService
            static IDataTransferManagerInterop DataTransferManagerInterop => DataTransferManager.As<IDataTransferManagerInterop>();
     #endif
     
    -       public async Task ShareRecipe(Recipe recipe, IImmutableList<Step> steps, CancellationToken ct)
    +       private async Task ShareRecipeCore(Recipe recipe, IImmutableList<Step> steps, CancellationToken ct)
            {
                    _recipe = recipe;
                    _steps = steps;
  3. For each method changed in (2), write a method with the original method declaration which invokes the Core suffixed method, wrapping the invocation in a try/catch block. The catch block should write the exception to the logger parameter, and re-throw the exception:

    	public async Task ShareRecipe(Recipe recipe, IImmutableList<Step> steps, CancellationToken ct)
    	{
    		try
    		{
    			await ShareRecipeCore(recipe, steps, ct);
    		}
    		catch (Exception ex)
    		{
    			logger.LogError(ex, "Failed to share recipe");
    			throw;
    		}
    	}

For example, the complete diff to ShareService is:

diff --git a/Chefs/Business/Services/Sharing/ShareService.cs b/Chefs/Business/Services/Sharing/ShareService.cs
index ec38f458..7149430e 100644
--- a/Chefs/Business/Services/Sharing/ShareService.cs
+++ b/Chefs/Business/Services/Sharing/ShareService.cs
@@ -6,7 +6,7 @@ using WinRT.Interop;
 
 namespace Chefs.Business.Services.Sharing;
 
-public class ShareService() : IShareService
+public class ShareService(ILogger<ShareService> logger) : IShareService
 {
 	private Recipe? _recipe;
 	private IImmutableList<Step>? _steps;
@@ -17,6 +17,19 @@ public class ShareService() : IShareService
 #endif
 
 	public async Task ShareRecipe(Recipe recipe, IImmutableList<Step> steps, CancellationToken ct)
+	{
+		try
+		{
+			await ShareRecipeCore(recipe, steps, ct);
+		}
+		catch (Exception ex)
+		{
+			logger.LogError(ex, "Failed to share recipe");
+			throw;
+		}
+	}
+
+	private async Task ShareRecipeCore(Recipe recipe, IImmutableList<Step> steps, CancellationToken ct)
 	{
 		_recipe = recipe;
 		_steps = steps;

Metadata

Metadata

Assignees

Labels

kind/bugSomething isn't workingtriage/untriagedIndicates an issue requires triaging or verification.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions