# frozen_string_literal: true RSpec.describe "handle exceptions", type: :integration do it "doesn't handle exceptions in development mode" do with_project do generate_action server do get "/books/1" expect(last_response.status).to eq(500) end end end it "doesn't handle exceptions in test mode" do with_project do generate_action RSpec::Support::Env["HANAMI_ENV"] = "test" server do get "/books/1" expect(last_response.status).to eq(500) end end end context "when handles exceptions in production mode" do it "it returns the expected status" do with_project do generate_action setup_production_env server do get "/books/1" expect(last_response.status).to eq(400) end end end context "and an exception is raised from a template" do it "it returns a 500 and it renders a custom template if it exists" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= raise ArgumentError.new("oh nooooo") %> EOF write "apps/web/templates/500.html.erb", <<~EOF This is a custom template for 500 error EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to eq("This is a custom template for 500 error\n") end end end it "it returns a 500 and it renders the default template if custom template doesn't exist" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= raise ArgumentError.new("oh nooooo") %> EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to include("

500 - Internal Server Error

") end end end it "it returns a 500 and renders backtrace error if an exception is raised from 500 custom template" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= raise ArgumentError.new("oh nooooo") %> EOF write "apps/web/templates/500.html.erb", <<~EOF <%= raise ArgumentError.new("Error from custom template") %> This is a custom template for 500 error EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to_not include("This is a custom template for 500 error") expect(last_response.body).to include("Error from custom template") end end end end context "and an exception is raised from a view" do it "it returns a 500 and it renders a custom template if it exists" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/views/books/show.rb", <<~EOF module Web::Views::Books class Show include Web::View def header raise ArgumentError.new("oh nooooo") end end end EOF rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= header %> EOF write "apps/web/templates/500.html.erb", <<~EOF This is a custom template for 500 error EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to eq("This is a custom template for 500 error\n") end end end it "it returns a 500 and it renders the default template if custom template doesn't exist" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/views/books/show.rb", <<~EOF module Web::Views::Books class Show include Web::View def header raise ArgumentError.new("oh nooooo") end end end EOF rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= header %> EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to include("

500 - Internal Server Error

") end end end it "it returns a 500 and renders backtrace error if an exception is raised from 500 custom template" do with_project do generate "action web books#show --url=/books/:id" rewrite "apps/web/views/books/show.rb", <<~EOF module Web::Views::Books class Show include Web::View def header raise ArgumentError.new("oh nooooo") end end end EOF rewrite "apps/web/templates/books/show.html.erb", <<~EOF <%= header %> EOF write "apps/web/templates/500.html.erb", <<~EOF <%= raise ArgumentError.new("Error from custom template") %> This is a custom template for 500 error EOF setup_production_env server do get "/books/1" expect(last_response.status).to eq(500) expect(last_response.body).to_not include("This is a custom template for 500 error") expect(last_response.body).to include("Error from custom template") end end end end end private def generate_action generate "action web books#show --url=/books/:id" rewrite "apps/web/controllers/books/show.rb", <<~EOF module Web::Controllers::Books class Show include Web::Action handle_exception ArgumentError => 400 def call(params) raise ArgumentError.new("oh nooooo") end end end EOF end def setup_production_env RSpec::Support::Env["HANAMI_ENV"] = "production" RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}" RSpec::Support::Env["SMTP_HOST"] = "localhost" RSpec::Support::Env["SMTP_PORT"] = "25" end end