From a6430692d2a2e10f23e0a2ba5e483111ef4199e4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 9 Jun 2023 18:22:40 +0200 Subject: [PATCH] Fix crash safe handling of internal errors and exceptions when drawing asset thumbnails #1138 --- .../Content/Thumbnails/ThumbnailsModule.cs | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs b/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs index 3e9274c83..a6996310e 100644 --- a/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs +++ b/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs @@ -242,21 +242,36 @@ namespace FlaxEditor.Content.Thumbnails if (!atlas.IsReady) return; - // Setup - _guiRoot.RemoveChildren(); - _guiRoot.AccentColor = request.Proxy.AccentColor; + try + { + // Setup + _guiRoot.RemoveChildren(); + _guiRoot.AccentColor = request.Proxy.AccentColor; - // Call proxy to prepare for thumbnail rendering - request.Proxy.OnThumbnailDrawBegin(request, _guiRoot, context); - _guiRoot.UnlockChildrenRecursive(); + // Call proxy to prepare for thumbnail rendering + request.Proxy.OnThumbnailDrawBegin(request, _guiRoot, context); + _guiRoot.UnlockChildrenRecursive(); - // Draw preview - context.Clear(_output.View(), Color.Black); - Render2D.CallDrawing(_guiRoot, context, _output); + // Draw preview + context.Clear(_output.View(), Color.Black); + Render2D.CallDrawing(_guiRoot, context, _output); - // Call proxy and cleanup UI (delete create controls, shared controls should be unlinked during OnThumbnailDrawEnd event) - request.Proxy.OnThumbnailDrawEnd(request, _guiRoot); - _guiRoot.DisposeChildren(); + // Call proxy and cleanup UI (delete create controls, shared controls should be unlinked during OnThumbnailDrawEnd event) + request.Proxy.OnThumbnailDrawEnd(request, _guiRoot); + } + catch (Exception ex) + { + // Handle internal errors gracefully (eg. when asset is corrupted and proxy fails) + Editor.LogError("Failed to render thumbnail icon for asset: " + request.Item); + Editor.LogWarning(ex); + request.FinishRender(ref SpriteHandle.Invalid); + RemoveRequest(request); + return; + } + finally + { + _guiRoot.DisposeChildren(); + } // Copy backbuffer with rendered preview into atlas SpriteHandle icon = atlas.OccupySlot(_output, request.Item.ID);