Skip to content

Fix unhandled ArgumentOutOfRangeException when exporting FlameGraph with unrendered canvas#2339

Merged
brianrob merged 7 commits intomainfrom
copilot/fix-unhandled-exception-flame-graph
Nov 21, 2025
Merged

Fix unhandled ArgumentOutOfRangeException when exporting FlameGraph with unrendered canvas#2339
brianrob merged 7 commits intomainfrom
copilot/fix-unhandled-exception-flame-graph

Conversation

Copy link
Contributor

Copilot AI commented Nov 21, 2025

  • Analyze the issue: ArgumentOutOfRangeException when saving FlameGraph with zero/invalid canvas size
  • Add validation in FlameGraph.Export() to check canvas size before creating RenderTargetBitmap
  • Add user-friendly error message when canvas size is invalid
  • Add try-catch in DoSaveFlameGraph to handle exception gracefully
  • Add test case to verify the fix
  • Address code review feedback - use string interpolation
  • Address PR review comments - change to ArgumentOutOfRangeException and shorten message
  • Capitalize 'Canvas' in error message per reviewer preference
  • Use nameof() for parameter name instead of hardcoding string
  • Run security scan
  • Final verification complete

Summary

Fixed unhandled ArgumentOutOfRangeException that occurred when saving a FlameGraph with an unrendered or invalid-sized canvas. The fix includes:

  1. Input validation: Added checks in FlameGraph.Export() to ensure canvas width and height are greater than zero before creating RenderTargetBitmap
  2. Proper exception type: Uses ArgumentOutOfRangeException which matches the original error from RenderTargetBitmap
  3. Graceful error handling: Wrapped the export call in a try-catch block to display user-friendly error messages via StatusBar.LogError()
  4. User feedback: Added success message when flame graph is saved successfully
  5. Test coverage: Added unit test to verify the fix
  6. Best practices: Uses nameof() operator for parameter names

All review comments have been addressed. The changes are minimal, focused, and directly address the reported issue.

Original prompt

This section details on the original issue you should resolve

<issue_title>Unhanded exception while trying to Save Flame Graph</issue_title>
<issue_description>I apologize for not sharing the offending ETL file, it contains proprietary information.

An unhanded exception occured.

. . .

The fact that this exception went unhanded is a programmer error.   It should be reported so it can be fixed.  Please set along the following stack trace information which will be useful in diagnosing the problem.

StackTrace:
System.ArgumentOutOfRangeException: The parameter value must be greater than zero.
Parameter name: pixelWidth
   at System.Windows.Media.Imaging.RenderTargetBitmap..ctor(Int32 pixelWidth, Int32 pixelHeight, Double dpiX, Double dpiY, PixelFormat pixelFormat)
   at PerfView.FlameGraph.Export(Canvas flameGraphCanvas, String filePath)
   at PerfView.StackWindow.DoSaveFlameGraph(Object sender, RoutedEventArgs e)
   at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
   at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
   at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
   at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
   at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
   at System.Windows.Input.CommandManager.TransferEvent(IInputElement newSource, ExecutedRoutedEventArgs e)
   at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
   at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)
   at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits November 21, 2025 02:25
Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
…t namespace usage

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unhandled exception while saving flame graph Fix unhandled ArgumentOutOfRangeException when exporting FlameGraph with unrendered canvas Nov 21, 2025
Copilot AI requested a review from brianrob November 21, 2025 02:29
Copy link
Member

@brianrob brianrob left a comment

Choose a reason for hiding this comment

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

@copilot, please address these comments.

// Validate that the canvas has a valid size before attempting to export
if (width <= 0 || height <= 0)
{
throw new InvalidOperationException(
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw new InvalidOperationException(
throw new ArgumentOutOfRangeException(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 0699b4a

{
throw new InvalidOperationException(
$"Cannot export flame graph: the canvas has an invalid size (width={width}, height={height}). " +
"Please ensure the flame graph is visible and has been rendered before attempting to export.");
Copy link
Member

Choose a reason for hiding this comment

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

The text here is too long to appear in the status bar. Please use this text: "Please ensure the flame graph is visible and has been rendered before attempting to export."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 0699b4a - shortened the error message to just the essential guidance

FlameGraph.Export(FlameGraphCanvas, saveDialog.FileName);
StatusBar.Log($"Saved flame graph to {saveDialog.FileName}");
}
catch (InvalidOperationException ex)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
catch (InvalidOperationException ex)
catch (ArgumentOutOfRangeException ex)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 0699b4a

try
{
// Attempt to export should throw InvalidOperationException with a meaningful message
var exception = Assert.Throws<InvalidOperationException>(() =>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
var exception = Assert.Throws<InvalidOperationException>(() =>
var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 0699b4a

…r message

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot, please address these comments.

All review comments addressed in commit 0699b4a:

  • Changed exception type from InvalidOperationException to ArgumentOutOfRangeException
  • Shortened error message text
  • Updated catch block and test to match new exception type

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copy link
Member

@brianrob brianrob left a comment

Choose a reason for hiding this comment

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

@copilot, please address these comments.

{
throw new ArgumentOutOfRangeException(
"flameGraphCanvas",
$"canvas has an invalid size (width={width}, height={height}). Please ensure the flame graph is visible and has been rendered before attempting to export.");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$"canvas has an invalid size (width={width}, height={height}). Please ensure the flame graph is visible and has been rendered before attempting to export.");
$"Canvas has an invalid size (width={width}, height={height}). Please ensure the flame graph is visible and has been rendered before attempting to export.");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 9f9e872

});

// Verify the exception message is helpful
Assert.Contains("canvas has an invalid size", exception.Message);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Assert.Contains("canvas has an invalid size", exception.Message);
Assert.Contains("Canvas has an invalid size", exception.Message);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 9f9e872

Co-authored-by: brianrob <6210322+brianrob@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 21, 2025

@copilot, please address these comments.

Both review comments addressed in commit 9f9e872 - capitalized 'Canvas' in error message and test assertion

Copilot AI requested a review from brianrob November 21, 2025 05:18
@brianrob brianrob marked this pull request as ready for review November 21, 2025 05:20
leculver
leculver previously approved these changes Nov 21, 2025
Copy link
Collaborator

@leculver leculver left a comment

Choose a reason for hiding this comment

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

One nitpick, but otherwise looks good to me.

Co-authored-by: leculver <8496639+leculver@users.noreply.github.com>
Copy link
Member

@StephenMolloy StephenMolloy left a comment

Choose a reason for hiding this comment

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

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unhanded exception while trying to Save Flame Graph

4 participants

Comments