Edgewall Software

Ticket #5516: show-enabled-plugins-in-error-page-r6658.diff

File show-enabled-plugins-in-error-page-r6658.diff, 6.5 KB (added by cboos, 10 months ago)

This adds the relevant plugins information to the error page. It also tries to identify the faulty plugins (this part needs to be expanded to handle plugins installed as eggs).

  • trac/htdocs/css/trac.css

     
    489489#content.error form.newticket { display: inline; } 
    490490#content.error form.newticket textarea { display: none; } 
    491491 
    492 #content.error #systeminfo { margin: 1em; width: auto; } 
    493 #content.error #systeminfo th { font-weight: bold; text-align: right; } 
     492#content.error #systeminfo, 
     493#content.error #plugins { margin: 1em; width: auto; } 
     494#content.error #systeminfo th, 
     495#content.error #plugins th { font-weight: bold; text-align: right; } 
    494496 
    495497#content.error #traceback { margin-left: 1em; } 
    496498#content.error #traceback :link, #content.error #traceback :visited { 
     
    504506  font-style: normal; 
    505507  font-weight: bold; 
    506508} 
    507 #content.error #traceback span.file { color: #666; font-size: 85%; } 
     509#content.error #traceback span.file, 
     510#content.error #plugins span.file { color: #666; font-size: 85%; } 
     511 
    508512#content.error #traceback ul { list-style: none; margin: .5em 0; padding: 0; } 
    509513#content.error #traceback ol { 
    510514  border: 1px dotted #d7d7d7; 
  • trac/admin/web_ui.py

     
    466466        if changes: 
    467467            self.config.save() 
    468468 
    469     def _render_view(self, req): 
     469    def get_plugins_data(self): 
    470470        plugins = {} 
    471471        plugins_dir = os.path.realpath(os.path.join(self.env.path, 'plugins')) 
    472472        plugins_dir = os.path.normcase(plugins_dir) # needs to match loader.py 
     
    530530        addons.sort() 
    531531        plugin_list += [plugins[category] for category in addons] 
    532532 
    533         data = { 
     533        return { 
    534534            'plugins': plugin_list, 
    535535            'readonly': not os.access(plugins_dir, os.F_OK + os.W_OK) 
    536536        } 
    537         return 'admin_plugins.html', data 
    538537 
     538    def _render_view(self, req): 
     539        return 'admin_plugins.html', self.get_plugins_data() 
     540 
    539541    def _find_distribution(self, module): 
    540542        path = get_module_path(module) 
    541543        if path == self.trac_path: 
  • trac/templates/error.html

     
    7171<py:for each="k, v in trac.systeminfo"> 
    7272|| '''$k''' || ${'`%s`' % (v and v.replace('\n', '` [[br]] `'))} ||</py:for> 
    7373 
     74<py:if test="plugins_list"> 
     75==== Enabled Plugins ==== 
     76<py:for each="plugin in plugins_list"> 
     77|| '''`$plugin.name`''' || $plugin.version || `$plugin.path` ||</py:for> 
     78</py:if> 
     79 
    7480==== Python Traceback ==== 
    7581{{{ 
    7682${traceback} 
     
    180186                  <td>$value</td> 
    181187                </tr> 
    182188              </table> 
     189              <py:if test="plugins_list"> 
     190                <h2>Enabled Plugins</h2> 
     191                <table class="listing" id="plugins"> 
     192                  <tr py:for="plugin in plugins_list"> 
     193                    <th py:with="url = plugin.info.home_page; 
     194                                 email = plugin.info.author_email; 
     195                                 report_url = url or email and 'mailto:'+email"> 
     196                        <a py:strip="not report_url" href="$report_url">$plugin.name</a> 
     197                    </th> 
     198                    <td>$plugin.version</td> 
     199                    <td> 
     200                      <span class="file"><a py:strip="not plugin.frame_idx" href="#frame$plugin.frame_idx">$plugin.path</a></span> 
     201                    </td> 
     202                  </tr> 
     203                </table> 
     204                <py:with vars="faulty_plugins = [p for p in plugins_list if 'frame_idx' in p]"> 
     205                  <p py:if="faulty_plugins" py:choose="len(faulty_plugins)"> 
     206                    <py:when test="1"> 
     207                      The ${faulty_plugins[0].name} seems to be involved in this problem.  
     208                    </py:when> 
     209                    <py:otherwise> 
     210                      The following plugins seem to be involved in this problem:  
     211                      ${', '.join([p.name for p in faulty_plugins])}. 
     212                    </py:otherwise> 
     213                    <br /> 
     214                    <strong>Please <em>first</em> report this issue to the plugin maintainer.</strong> 
     215                  </p> 
     216                </py:with> 
     217              </py:if> 
     218 
    183219            </py:otherwise> 
    184220          </py:choose> 
    185221        </py:when> 
  • trac/web/main.py

     
    3939from trac.perm import PermissionCache, PermissionError, PermissionSystem 
    4040from trac.resource import ResourceNotFound 
    4141from trac.util import get_lines_from_file, get_last_traceback, hex_entropy 
    42 from trac.util.compat import partial, reversed 
     42from trac.util.compat import partial, reversed, any 
    4343from trac.util.datefmt import format_datetime, http_date, localtz, timezone 
    4444from trac.util.text import shorten_line, to_unicode 
    4545from trac.web.api import * 
     
    471471                                    'vars': tb.tb_frame.f_locals}] 
    472472                    tb = tb.tb_next 
    473473 
     474            # TODO: move get_plugins_data at trac.admin.web_ui toplevel 
     475            from trac.admin.web_ui import PluginAdminPanel 
     476            plugins_data = PluginAdminPanel(env).get_plugins_data() 
     477            # only consider plugins that have at least one component enabled 
     478            plugins_list = [p for p in plugins_data['plugins'][1:] 
     479                            if any([c['enabled'] for c in p['components']])] 
     480            # check whether a plugin is involved in the backtrace 
     481            # FIXME: this currently only works well for single-file plugins  
     482            #        those installed in develop mode 
     483            for plugin in plugins_list: 
     484                plugin_base = os.path.splitext(plugin['path'])[0] 
     485                for i, f in enumerate(frames): 
     486                    if f['filename'].startswith(plugin_base): 
     487                        plugin['frame_idx'] = i 
     488                        break 
     489 
    474490            data = {'title': 'Internal Error', 
    475491                    'type': 'internal', 'message': message, 
    476492                    'traceback': traceback, 'frames': frames, 
    477                     'shorten_line': shorten_line} 
     493                    'shorten_line': shorten_line,  
     494                    'plugins_list': plugins_list} 
    478495 
    479496            try: 
    480497                req.send_error(exc_info, status=500, env=env, data=data)