<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: UI Elements to Intercept Exceptions? in ArcGIS Pro SDK Questions</title>
    <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/ui-elements-to-intercept-exceptions/m-p/1411118#M11384</link>
    <description>&lt;P&gt;i think you are trying to do something like this:&amp;nbsp;&lt;A href="https://stackoverflow.com/questions/1472498/wpf-global-exception-handler" target="_blank"&gt;https://stackoverflow.com/questions/1472498/wpf-global-exception-handler&lt;/A&gt;&lt;/P&gt;&lt;P&gt;I, myself, have never tried it.&lt;/P&gt;</description>
    <pubDate>Wed, 17 Apr 2024 18:14:05 GMT</pubDate>
    <dc:creator>CharlesMacleod</dc:creator>
    <dc:date>2024-04-17T18:14:05Z</dc:date>
    <item>
      <title>UI Elements to Intercept Exceptions?</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/ui-elements-to-intercept-exceptions/m-p/1407320#M11364</link>
      <description>&lt;P&gt;I'm working on a Module for Pro v3.3 that I would like to catch and handle (as gracefully as possible) all exceptions that are thrown from within the module.&amp;nbsp; A primary goal is to ensure that exceptions that result from &lt;U&gt;&lt;EM&gt;&lt;STRONG&gt;my&lt;/STRONG&gt;&lt;/EM&gt;&lt;/U&gt; mistakes get logged to&amp;nbsp;&lt;U&gt;&lt;EM&gt;&lt;STRONG&gt;my&lt;/STRONG&gt;&lt;/EM&gt;&lt;/U&gt; logging system not Esri's (my users never see the "Send Esri an Error Report" dialog).&amp;nbsp; To that end, I've made an abstract class that inherits from `Button`, and from which all button classes in our module should inherit (pertinent excerpt below)...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;/// &amp;lt;summary&amp;gt;
/// Base from which all buttons should inherit
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;remarks&amp;gt;
/// The primary reason for the existence of this class and &amp;lt;see cref="Tools.WrEditTool"/&amp;gt; is to ensure no exceptions thrown inside
/// WREdit bubble up to ArcMap because that's when people are prompted to send exception information to Esri.All buttons should
/// inherit from this class, which executes the "ClickAction" in its OnClick event and wraps it in a try/catch that catches &amp;amp; logs
/// everything that it cannot handle more gracefully.
/// &amp;lt;/remarks&amp;gt;
public abstract class WrEditButton : Button
{
    /// &amp;lt;summary&amp;gt;
    /// Message to be shown to user in the event of an unhandled exception
    /// &amp;lt;/summary&amp;gt;
    protected virtual string UnhandledExceptionUserMessage =&amp;gt; "Unhandled exception encountered while using this command";


    /// &amp;lt;summary&amp;gt;
    /// Action to be taken when the button is clicked.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;This will be wrapped in a try/catch statement and possibly other stuff too&amp;lt;/remarks&amp;gt;
    protected abstract void ClickAction();

    /// &amp;lt;inheritdoc cref="Button.OnClick"/&amp;gt;
    protected sealed override void OnClick()
    {
        Cursor preExistingCursor = Mouse.OverrideCursor; // This is supposed to get the current mouse cursor. Not sure if it does that.
        FrameworkApplication.SetCursor(Cursors.Wait); // This is supposed to set the application's mouse cursor to "wait", but it doesn't work.
        try
        {
            ClickAction();
        }
        catch (Exception exception)
        {
            WrEditModule.HandleException(exception, UnhandledExceptionUserMessage);
        }
        finally
        {
            FrameworkApplication.SetCursor(preExistingCursor); // This is supposed to set the application's mouse cursor back to previous, but it doesn't work.
        }
    }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;... and ...&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;internal class WrEditModule : Module
{
    /// &amp;lt;summary&amp;gt;
    /// This is the general exception handler for WREdit's UI.  If there is a reaction to a particular exception
    /// that should be globally applied, this is the place to apply it.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="exception"&amp;gt;Exception to be handled&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="userMessage"&amp;gt;Message to be shown to the user in the case of an unexpected exception&amp;lt;/param&amp;gt;
    internal static void HandleException(   // TODO: Should this be placed somewhere else?
        Exception exception,
        string userMessage)
    {
        try
        {
            var activeMapView = MapView.Active;
            if (activeMapView != null 
                &amp;amp;&amp;amp; activeMapView.Map != null 
                &amp;amp;&amp;amp; activeMapView.Map.ContainsDuplicateLayerNames(out string[] names))
            {
                var commaSeparatedLayerNames = string.Join(", ", names);
                userMessage =
                    $"{userMessage.Trim()}\n\nSay, we noticed that there are multiple layers in the " +
                    $"map with the following name(s): [{commaSeparatedLayerNames}]. " +
                    "Can you please try renaming those layers to have unique names?";
            }

            var logLevel = LogEventLevel.Error;
            string logMessage;
            try
            {
                var userProcessManager = GetDependency&amp;lt;IUserProcessManager&amp;gt;();
                logMessage = userProcessManager.DatabaseState.ToString();
            }
            catch
            {
                logMessage = "Unable to retrieve user's WrEditInterface record.";
            }
            switch (exception)
            {
                case UserActionException userActionException:
                    logMessage = $"{logMessage}\n\n{userActionException.LogMessage}";
                    userMessage = userActionException.UserActionMessage;
                    logLevel = LogEventLevel.Warning;
                    break;
                case InvalidGeometryException invalidGeometryException:
                    logMessage = $"{logMessage}\n\n{exception.Message}:  \n\n{invalidGeometryException.WellKnownText}\n\n";
                    break;
            }

            var innerException = exception;
            while (innerException is not null)
            {
                if (//innerException is System.Data.SqlClient.SqlException &amp;amp;&amp;amp;  TODO: Figure out what exception type this is through EF Core
                    innerException.Message.Contains("Timeout") &amp;amp;&amp;amp;
                    innerException.Message.Contains("Expired"))
                {
                    userMessage = $"{userMessage.Trim()}\n\nWREdit experienced a 'network hiccup' that prevented it from writing to the database. Please try again later.";
                    break;
                }
                innerException = innerException.InnerException;
            }

            Log.Logger.Write(logLevel, exception, logMessage);
            MessageBox.Show(userMessage);
            //MessageBox.Show(      TODO: Figure out how to specify buttons &amp;amp; icons (hafta add a bunch more parameter values)
            //    caption:userMessage,
            //    button: MessageBoxButton.OK,
            //    icon:MessageBoxImage.Exclamation);
        }
        catch (Exception ex)
        {
            Log.Logger.Error(ex, "Fatal error handling an exception");
        }
    }
}&lt;/LI-CODE&gt;&lt;P&gt;Has anyone else embarked upon anything like this? I'm new to MVVM &amp;amp; WPF (this is a port from ArcMap), so &lt;EM&gt;&lt;U&gt;I'm especially keen to know if anyone's tried anything similar with an abstract ViewModel class or extending RelayCommand or . . . anything.&amp;nbsp;&lt;/U&gt;&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 08 Apr 2024 21:59:00 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/ui-elements-to-intercept-exceptions/m-p/1407320#M11364</guid>
      <dc:creator>DanNarsavage_IDWR</dc:creator>
      <dc:date>2024-04-08T21:59:00Z</dc:date>
    </item>
    <item>
      <title>Re: UI Elements to Intercept Exceptions?</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/ui-elements-to-intercept-exceptions/m-p/1411118#M11384</link>
      <description>&lt;P&gt;i think you are trying to do something like this:&amp;nbsp;&lt;A href="https://stackoverflow.com/questions/1472498/wpf-global-exception-handler" target="_blank"&gt;https://stackoverflow.com/questions/1472498/wpf-global-exception-handler&lt;/A&gt;&lt;/P&gt;&lt;P&gt;I, myself, have never tried it.&lt;/P&gt;</description>
      <pubDate>Wed, 17 Apr 2024 18:14:05 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/ui-elements-to-intercept-exceptions/m-p/1411118#M11384</guid>
      <dc:creator>CharlesMacleod</dc:creator>
      <dc:date>2024-04-17T18:14:05Z</dc:date>
    </item>
  </channel>
</rss>

