2015-04-26 2 views
1

Я пытаюсь обрабатывать ошибки в модульном приложении Sinatra. Мы поднимаем различные ошибки из приложения, и я написал кое-что, чтобы поймать ошибки, думая, что это произойдет иерархически.Sinatra Catching Exceptions для пользовательских страниц ошибок

Этот файл, который я использую для обработки ошибок, выглядит следующим образом.

#!/usr/bin/env ruby 

# @class  class RApp 
# @brief  Sinatra main routes overloading for App class 
class RApp < Sinatra::Base 

    # @fn   not_found do {{{ 
    # @brief  Not found error page 
    not_found do 
    render_error 404, _('Not Found'), env['sinatra.error'].message 
    end # }}} 

    # @fn   error ServiceNotAvailableError do {{{ 
    # @brief  Handle ServiceNotFoundException, commonly associated with communication 
    #    errors with external required services like Ambrosia, Saba 
    error ServiceNotAvailableError do 
    render_error 503, _('Service Not Available'), env['sinatra.error'].message 
    end # }}} 

    # @fn   error Exception do {{{ 
    # @brief  Handle general internal errors 
    error Exception do 
    render_error 500, _('Internal Server Error'), env['sinatra.error'].message 
    end # }}} 

    error DBC::InvalidUUIDError do 
    "Invalid UUID Error" 
    end 

    # @fn   def show_error code, title, message, view = nil {{{ 
    # @brief  Displays the proper message (html or text) based on if the request is XHR or otherwise 
    def render_error code, title, message, view = nil 
    view = code.to_s if view.nil? 

    if request.xhr? 
     halt code, message 
    else 
     halt code, slim(:"error_pages/#{view}", locals: {title: title, message: message}) 
    end 
    end # }}} 

    # Just for testing 
    get '/errors/:type' do |type| 
    raise Object.const_get(type) 
    end 

end # of class RApp < Sinatra::Base }}} 

# vim:ts=2:tw=100:wm=100 

Я думал, что он попытается выполнить заказ в файле, который кажется правдой.

Как бы то ни было, вопрос Exception не охватывает все исключения.

Например, у меня есть DBC::InvalidUUIDError что в качестве такого

  • DBC::InvalidUUIDErrror < DBC::Error
  • DBC::Error < RuntimeError
  • , который я понимаю, как в Руби RuntimeError < Exception

Но error Exception не улавливает все Exception как Я думал.

Я делаю что-то неправильно? Или вообще невозможно поймать все исключения?

Примечание: В дополнение к предоставленным ответам (обе работы) у меня было set :raise_errors, true. Вам не нужно устанавливать его в процессе разработки и производства. По умолчанию он установлен для 'test' env.

Характер дела был некоторыми исключениями, и некоторые не были обработаны.

ответ

2

Добавить это, чтобы предотвратить собственную страницу ошибки Синатры от вмешательства пользовательских обработчиков ошибок:

set :show_exceptions, false 

По умолчанию параметр истинна в режиме разработки, и ложна в производстве.

Обратите внимание, что если вы будете следовать советам Синатра файлы README о настройке set :show_exceptions, :after_handler, что позволит обработчики ошибок работать даже в режиме разработки (по крайней мере некоторые классы исключений), но также позволит встроенный страница ошибки в производстве для исключенных исключений. И мне непонятно, какие обработчики ошибок он будет уважать, и какие из них будут игнорировать в пользу встроенной страницы отладки.

Редактировать: Я понял, что вы также спросили о порядке определения обработчиков ошибок. Это не имеет значения; Sinatra сначала ищет точные соответствия классу исключений в классе приложения, а затем в своих суперклассах. Если он не находит его, он повторяет поиск суперкласса исключения и т. Д. Таким образом, обработчик для исключения будет вызван только для исключений, для которых не существует более близкого совпадения.

+0

Интересная находка. Он извлекает исключения по желанию в рабочей среде. Но, как вы сказали, только некоторые ошибки фиксируются в режиме разработки. То есть, когда у меня есть 'disable: show_exceptions' –

3

Вот соответствующая информация от Sinatra docs:

Sinatra устанавливает специальные NOT_FOUND и ошибок обработчиков при работе в среде разработки, чтобы отобразить хорошие следы стека и дополнительную отладочную информацию в вашем браузере.

Что это означает, что когда вы работаете в развитии, Синатр имеет создает по умолчанию «поймать-все» обработчик ошибок, который имеет более высокий приоритет, чем ваш error Exception do .. end блок.

После того, как вы вошли в режим производства, (или отключите его в dev через disable :show_exceptions ), ваш блок error Exception do .. end должен занять все ваши исключения.

Обратите внимание, что порядок указанных error блоков не имеет значения.

Смежные вопросы