Class: Cosmos::ExceptionDialog

Inherits:
Object
  • Object
show all
Defined in:
lib/cosmos/gui/dialogs/exception_dialog.rb

Overview

Creates a dialog to display a COSMOS exception to the user. The dialog can close the application and log the exception. This is the primary dialog to display when something goes unexpectedly wrong.

Constant Summary collapse

@@mutex =

Returns Mutex to make this dialog single threaded.

Returns:

  • (Mutex)

    Mutex to make this dialog single threaded

Mutex.new

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, exception, title = 'COSMOS Exception', exit_afterwards = true, log_exception = true, log_file = nil) ⇒ ExceptionDialog

Returns a new instance of ExceptionDialog.

Parameters:

  • parent (Qt::Dialog)

    Parent of this dialog

  • exception (Exception)

    Ruby Exception to display details about

  • title (String) (defaults to: 'COSMOS Exception')

    Title of the dialog

  • exit_afterwards (Boolean) (defaults to: true)

    Whether to completely exit the application after displaying the dialog. Useful for fatal exceptions.

  • log_exception (Boolean) (defaults to: true)

    Whether to create an exception log file

  • log_file (String) (defaults to: nil)

    Name of the log file to create



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/cosmos/gui/dialogs/exception_dialog.rb', line 32

def initialize(parent, exception, title = 'COSMOS Exception', exit_afterwards = true, log_exception = true, log_file = nil)
  return unless @@mutex.try_lock

  unless exception.class == SystemExit || exception.class == Interrupt
    # ConfigParser::Errors are configuration user errors. We don't want to clutter
    # up list of real exceptions with user configuration errors.
    # Same goes for FatalErrors
    unless exception.class == ConfigParser::Error || exception.class == FatalError
      log_file = Cosmos.write_exception_file(exception) if log_exception
    end

    if Qt::CoreApplication.instance
      msg = Qt::MessageBox.new(parent)
      msg.setWindowTitle(title)
      msg.setTextFormat(Qt::RichText)
      msg.setIcon(Qt::MessageBox::Critical)
      case exception
      # ConfigParser::Errors are a special case generated with a known format
      # by the ConfigParser
      when ConfigParser::Error
        # Substitute the html tags '<' and '>' and then replace newlines with html breaks
        if exception.usage && !exception.usage.empty?
          usage = "Usage: #{exception.usage.gsub("<", "&#060;").gsub(">", "&#062;").gsub("\n", "<br/>")}<br/><br/>"
        else
          usage = ''
        end
        if exception.message && !exception.message.empty?
          message = exception.message.gsub("<", "&#060;").gsub(">", "&#062;").gsub("\n", "<br/>")
        else
          message = ''
        end
        if exception.keyword && exception.parameters
          line = exception.keyword + ' ' + exception.parameters.join(' ').gsub("<", "&#060;").gsub(">", "&#062;").gsub("\n", "<br/>") + "<br/><br/>"
        else
          line = ''
        end
        text = "#{line}#{usage}#{message}"
        if exception.filename && exception.line_number
          text = "Error at #{exception.filename}:#{exception.line_number}<br/><br/>#{text}"
        end
        if exception.url && !exception.url.empty?
          text << "<br/><br/>For more information see <a href='#{exception.url}'>#{exception.url}</a>."
        end
      # FatalErrors are errors explicitly raised when a known fatal issue
      # occurs. Since it is a known issue we don't put up the full error
      # dialog.
      when FatalError
        text = "Error: #{exception.message.gsub("\n", "<br/>")}"
      else
        file_contents = ""
        # First read the log_file we wrote out to the logs directory
        # Change newlines to %0A for Outlook and remove all quotes to avoid breaking the link
        begin
          message = exception.message.gsub("\n", "<br/>")
          file_contents = File.read(log_file).gsub("\n", "%0A").gsub("'", "").gsub("\"", "") if log_file
        rescue
        end
        text = "The following error occurred:<br/>#{message}"
        text << "<br/><br/>Please contact your local COSMOS expert.<br/><br/>This error has been logged:<br/>#{log_file}<br/><br/> <a href='mailto:[email protected];[email protected]?subject=COSMOS exception&body=#{file_contents}'>Click here</a> to email this log to the COSMOS developers." if log_file
      end
      text << "<br/><br/>NOTE!: The application will exit once you accept or dismiss this dialog!" if exit_afterwards
      msg.setText(text)
      if log_file
        open_button = Qt::PushButton.new("Open Exception Log in Text Editor")
        open_button.connect(SIGNAL('clicked()')) do
          Cosmos.open_in_text_editor(log_file)
          sleep(2)
        end
        msg.addButton(open_button, Qt::MessageBox::ResetRole)
      end
      close_button = Qt::PushButton.new("Close")
      msg.addButton(close_button, Qt::MessageBox::ActionRole)
      msg.raise
      msg.exec
      msg.dispose
    end # if Qt::CoreApplication.instance
  end #  unless exception.class == SystemExit or exception.class == Interrupt
  @@mutex.unlock
  if exit_afterwards
    Qt::CoreApplication.instance.exit(1) if Qt::CoreApplication.instance
    exit 1 # incase CoreApplication doesn't exit yet or didn't complete the exit
  end
end

Class Method Details

.dialog_open?Boolean

Returns Whether this dialog has already been instantiated.

Returns:

  • (Boolean)

    Whether this dialog has already been instantiated



117
118
119
# File 'lib/cosmos/gui/dialogs/exception_dialog.rb', line 117

def self.dialog_open?
  @@mutex.locked?
end