Todd
Todd

Reputation: 692

Sinatra, sending an empty page

This is the tail end of my code within a route block. What's happening is that the success_loader never renders and instead Sinatra sends a null response (page is blank)

if v.test
  mydata = v.sheetData
end
if v.errors.size == 0
  #success
  haml :success_loader, :layout => :base, 
       :locals => {:pub_path => settings.root, :app_ver => settings.version }
else
  #fail
  haml :failure_loader, :layout => :base, 
       :locals => {:pub_path => settings.root, :app_ver => settings.version, 
       :app_error => v.errors }
end 
File.delete(target) if File.exists?(target)

Using debugger I show each line starting at the point where the call to haml begins

haml :success_loader, :layout => :base, 
     :locals => {:pub_path => settings.root, :app_ver => settings.version }
getter = proc { value }

value = :pub_path

getter = proc { value }

value = :apper_ver

File.delete(target) if File.exists?(target)
@params = @original_params
filter! :after unless env['sinatra.static_file']
res = [res] if Fixnum === res or String === res
if Array === res and Fixnum === res.first
status(res.shift)
body(res.pop)
headers(*res)
invoke { error_block!(response.status) }
unless @response['Content-Type'

bunch more similar lines. Then several lines from Thin beginning with this:

log "!! Rack application returned nil body. Probably you wanted it to be an empty string?" if @response.body.nil?

I tested the code outside the route so it's not throwing any exception. The haml templates work fine when used in other routes. Any ideas what's going on?

Upvotes: 0

Views: 650

Answers (1)

ian
ian

Reputation: 12251

The body will be the last thing evaluated in the route block. The last thing is:

File.delete(target) if File.exists?(target)

The docs for File.delete tell us:

Deletes the named files, returning the number of names passed as arguments.

So I'm guessing that target didn't exist or was nil, something that would make that statement evaluate to nil.

If you want to set the body earlier than the end, use the body helper:

body = if v.errors.size == 0
  #success
  haml :success_loader, :layout => :base, 
       :locals => {:pub_path => settings.root, :app_ver => settings.version }
else
  #fail
  haml :failure_loader, :layout => :base, 
       :locals => {:pub_path => settings.root, :app_ver => settings.version, 
       :app_error => v.errors }
end 
File.delete(target) if File.exists?(target)

but this can be refactored a bit to:

template = v.errors.size == 0 ? :success_loader : :failure_loader
File.delete(target) if File.exists?(target)
haml template, :layout => :base, 
               :locals => {
                 :pub_path => settings.root,
                 :app_ver => settings.version, 
                 :app_error => v.errors
               }.delete_if{|k,v| v.nil?}

Upvotes: 1

Related Questions