Skip to content

Fix compilation error and address high/medium priority code audit issues#59

Merged
johnpierson merged 2 commits into
masterfrom
copilot/fix-missing-debug-namespace
Feb 23, 2026
Merged

Fix compilation error and address high/medium priority code audit issues#59
johnpierson merged 2 commits into
masterfrom
copilot/fix-missing-debug-namespace

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 21, 2026

The codebase referenced a non-existent MonocleViewExtension.Debug namespace and PlaceAllNodes class (compilation blocker), and had several resource management and correctness issues identified in a code audit.

Changes

Critical: Remove non-existent Debug namespace (MonocleViewExtension.cs)

  • Removed using MonocleViewExtension.Debug; and the PlaceAllNodes.AddMenuItem(debugMenu, p) block — neither the namespace nor the class exist in the repository

High: Fix resource leaks (Utilities/Settings.cs)

Replaced manual Close() calls with using statements:

// Before
var writer = new StreamWriter(filename);
xmls.Serialize(writer, settings);
writer.Close();

// After
using (var writer = new StreamWriter(filename))
{
    xmls.Serialize(writer, settings);
}

Same pattern applied to FileStream in DeserializeModels.

High: Implement Dispose() (MonocleViewExtension.cs)

Previously empty; now unsubscribes the AssemblyResolve handler registered in Startup():

public void Dispose()
{
    AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainOnAssemblyResolve;
}

Medium: Remove duplicate keyboard shortcut registration (PackageUsageCommand.cs)

Ctrl+Shift+P was registered twice in RegisterKeyboardShortcuts() — once inside the try/catch and again unconditionally after it. Removed the redundant second registration.

Medium: Guard against null PmExtension (PackageUsageModel.cs)

GetPackageVersion() could throw if PackageManagerExtension wasn't loaded. Added an early-return null check:

if (Globals.PmExtension?.PackageLoader == null) return "";
Original prompt

This section details on the original issue you should resolve

<issue_title>Code Audit: Issues and Proposed Fixes</issue_title>
<issue_description># Code Audit: Issues and Proposed Fixes

Summary

A comprehensive code audit of the Monocle codebase revealed several issues ranging from critical compilation blockers to code quality improvements. This issue documents all findings with proposed fixes.


🔴 Critical Issues

1. Missing Debug Namespace (Compilation Error)

Location: MonocleViewExtension.cs:21-22, 87-90

Problem: The code imports MonocleViewExtension.Debug and calls PlaceAllNodes.AddMenuItem() but there's no Debug folder or corresponding source files in the repository.

using MonocleViewExtension.Debug; // Line 21 - namespace doesn't exist

// Line 87-90
var debugMenu = p.dynamoMenu.Items.OfType<MenuItem>().FirstOrDefault(m => m.Header.Equals("De_bug"));
if (debugMenu != null)
{
    PlaceAllNodes.AddMenuItem(debugMenu,p); // PlaceAllNodes class doesn't exist
}

Fix: Either:

  1. Add the missing Debug/PlaceAllNodes files to the repository, or
  2. Remove the using statement and the PlaceAllNodes code block

🟠 High Priority Issues

2. Resource Disposal - File Streams Not Closed

Location: Utilities/Settings.cs:66-70, 56-60

Problem: FileStream and StreamWriter are not properly disposed, which can lead to file locks and resource leaks.

// Current code in SerializeModels
public static void SerializeModels(string filename, MonocleSettings settings)
{
    var xmls = new XmlSerializer(settings.GetType());
    var writer = new StreamWriter(filename);  // Not disposed!
    xmls.Serialize(writer, settings);
    writer.Close();  // Close is not the same as Dispose
}

Fix: Use using statements:

public static void SerializeModels(string filename, MonocleSettings settings)
{
    var xmls = new XmlSerializer(settings.GetType());
    using (var writer = new StreamWriter(filename))
    {
        xmls.Serialize(writer, settings);
    }
}

public static MonocleSettings DeserializeModels(string filename)
{
    using (var fs = new FileStream(filename, FileMode.Open))
    {
        var xmls = new XmlSerializer(typeof(MonocleSettings));
        return (MonocleSettings)xmls.Deserialize(fs);
    }
}

3. Empty Dispose Method

Location: MonocleViewExtension.cs:28-29

Problem: The Dispose method is empty, but the extension registers event handlers that should be unsubscribed.

public void Dispose()
{
}

Fix:

public void Dispose()
{
    AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainOnAssemblyResolve;
    // Unsubscribe from any other event handlers
}

4. Hardcoded User Paths in Project File

Location: Monocle.csproj:104-106, 108-110

Problem: Hardcoded paths to specific user directories will break builds for other developers.

<FolderPackages>C:\Users\piersoj\Documents\Repos\MonocleForDynamo\deploy\$(BuildOutput)\</FolderPackages>
<StartProgram>C:\Users\johnpierson\Desktop\Autodesk\DynamoCoreRuntime2.19.3\DynamoSandbox.exe</StartProgram>

Fix: Use relative paths or environment variables:

<FolderPackages>$(MSBuildProjectDirectory)\deploy\$(BuildOutput)\</FolderPackages>
<StartProgram Condition="Exists('$(DynamoPath)')">$(DynamoPath)\DynamoSandbox.exe</StartProgram>

🟡 Medium Priority Issues

5. Silent Exception Swallowing

Location: Multiple files

Many catch blocks silently swallow exceptions, making debugging difficult:

Examples:

  • Utilities.cs:62-65 - ImageUtils.LoadImage
  • Utilities.cs:162-165 - Compatibility.FixThemesForDevExpress
  • FocaModel.cs:73-76, 93-96 - ReplaceDropdown
  • InlineNodeConnectomaticModel.cs:85-88

Fix: At minimum, log the exception:

catch (Exception e)
{
    Dynamo.Logging.LogMessage.Warning($"Monocle - {e.Message}", WarningLevel.Mild);
}

6. Duplicate Keyboard Shortcut Registration

Location: PackageUsage/PackageUsageCommand.cs:106-155

Problem: The PackageUsageCommand keyboard shortcut (Ctrl+Shift+P) is registered twice - once in RegisterKeyboardShortcuts() and again at the end of the method.

// First registration (lines 70-83)
var packageUsage = new CommandBinding(new RoutedUICommand("PackageUsage", ...));

// Second registration (lines 106-128) - DUPLICATE
InputGestureCollection gestures = new InputGestureCollection
{
    new KeyGesture(Key.P, ModifierKeys.Control | ModifierKeys.Shift)
};
RoutedUICommand uiCommand = new RoutedUICommand("PackageUsage", ...);

Fix: Remove the duplicate code block (lines 106-128).

7. Potential Null Reference - PackageManagerExtension

Location: MonocleViewExtension.cs:63

Globals.PmExtension = p.ViewStartupParams.ExtensionManager.Extensions.OfType<PackageManagerExtension>().FirstOrDefault();

Globals.PmExtension is later used without null checking in `PackageUsageMode...


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

…isposal, implement Dispose, remove duplicate shortcut, add null check

Co-authored-by: johnpierson <15744724+johnpierson@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix missing debug namespace compilation error Fix compilation error and address high/medium priority code audit issues Feb 21, 2026
Copilot AI requested a review from johnpierson February 21, 2026 22:23
@johnpierson johnpierson marked this pull request as ready for review February 22, 2026 03:01
@johnpierson
Copy link
Copy Markdown
Owner

@copilot are we removing the entire boring window? Or is it just the keyboard command assignment duplication?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot are we removing the entire boring window? Or is it just the keyboard command assignment duplication?

Just the duplicate keyboard shortcut registration was removed — the boring window (PackageUsageView) is fully intact in two places:

  1. Menu item click handler (lines 57–82) — clicking the menu item still opens the boring window as before
  2. Keyboard shortcut handler (lines 138–161, inside RegisterKeyboardShortcuts) — Ctrl+Shift+P still opens the boring window

What was removed was a second, identical Ctrl+Shift+P binding that was registered outside the try/catch block after all the other shortcuts, which would have caused the same shortcut to fire two handlers and open two windows simultaneously.

Copy link
Copy Markdown
Owner

@johnpierson johnpierson left a comment

Choose a reason for hiding this comment

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

lgtm mr/mrs copilot

@johnpierson johnpierson merged commit 3d6948f into master Feb 23, 2026
1 check passed
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.

Code Audit: Issues and Proposed Fixes

2 participants