Custom 500's
authorBlake Mizerany <blake@blake.local>
Fri, 30 Nov 2007 01:56:18 +0000 (29 17:56 -0800)
committerBlake Mizerany <blake@blake.local>
Fri, 30 Nov 2007 01:56:18 +0000 (29 17:56 -0800)
lib/sinatra.rb
test/custom_error_test.rb [new file with mode: 0644]

index a52eedc..3fb90a6 100644 (file)
@@ -258,27 +258,44 @@ module Sinatra
         '<h1>Not Found</h1>'
       end
     end
+    
+    def basic_error
+      Error.new(500) do
+        '<h1>Internal Server Error</h1>'
+      end
+    end
 
     def options
       @options ||= OpenStruct.new(default_options)
     end
     
     def call(env)
-      result = lookup(env)
-      context = EventContext.new(
-        Rack::Request.new(env), 
-        Rack::Response.new,
-        result.params
-      )
-      context.status(result.status)
-      returned = catch(:halt) do
-        [:complete, context.instance_eval(&result.block)]
+      body = nil
+      begin
+        result = lookup(env)
+        context = EventContext.new(
+          Rack::Request.new(env), 
+          Rack::Response.new,
+          result.params
+        )
+        context.status(result.status)
+        returned = catch(:halt) do
+          [:complete, context.instance_eval(&result.block)]
+        end
+        body = returned.to_result(context)
+      rescue => e
+        env['sinatra.error'] = e
+        result = (events[:errors][500] || basic_error).invoke(env)
+        returned = catch(:halt) do
+          [:complete, context.instance_eval(&result.block)]
+        end
+        body = returned.to_result(context)
+        context.status(500)
       end
-      result = returned.to_result(context)
-      context.body = String === result ? [*result] : result
+      context.body = String === body ? [*body] : body
       context.finish
     end
-        
+    
   end
   
 end
diff --git a/test/custom_error_test.rb b/test/custom_error_test.rb
new file mode 100644 (file)
index 0000000..6bd3f3e
--- /dev/null
@@ -0,0 +1,49 @@
+require File.dirname(__FILE__) + '/helper'
+
+context "Custom Errors (in general)" do
+
+  specify "override the default 404" do
+    
+    get_it '/'
+    should.be.not_found
+    body.should.equal '<h1>Not Found</h1>'
+    
+    error 404 do
+      'Custom 404'
+    end
+    
+    get_it '/'
+    should.be.not_found
+    body.should.equal 'Custom 404'
+    
+  end
+  
+  specify "override the default 500" do
+    
+    get '/' do
+      raise 'asdf'
+    end
+    
+    get_it '/'
+    status.should.equal 500
+    body.should.equal '<h1>Internal Server Error</h1>'
+    
+    
+    error 500 do
+      'Custom 500 for ' + request.env['sinatra.error'].message
+    end
+    
+    get_it '/'
+    
+    get_it '/'
+    status.should.equal 500
+    body.should.equal 'Custom 500 for asdf'
+    
+  end
+
+end
+
+
+
+
+