Raises "Unsupported block result" when using Unreloader and json plugin
Closed this issue ยท 2 comments
Hi Jeremy, I am getting a Roda::RodaError: unsupported block result
using Ruby 3.1.3 on an M1 Mac.
Let me admit, that I am not 100 % sure whether it's a bug or not. ๐
It's a basic Roda example using Unreloader.
Here's the example code that provokes the error:
# app.rb
class App < Roda
use Rack::Deflater # <<- enable gzip
plugin :json
route do |r|
r.root do
{ hello: 'world',
lorem: 'lorem ipsum dolor sit amet!' }
end
# /:int
r.on Integer do |x|
# /:int
r.on Integer do |y|
{ data: {add: x + y,
multiply: x * y} }
end
end
end
end
# config.ru
require 'rubygems'
require 'bundler/setup'
Bundler.require
require 'rackup'
require 'rack/deflater'
require 'rack/unreloader'
require 'roda'
Unreloader = Rack::Unreloader.new{App}
Unreloader.require 'app.rb'
run Unreloader
# Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "rack", "~> 3.0"
gem "rackup", "~> 0.2.3"
gem "roda", "~> 3.62"
gem "webrick", "~> 1.7"
gem "rack-unreloader", "~> 2.0"
After the initial rackup
everything is fine, but changing something in the return value of the hash yielding the math results - it's when the crash appears.
Roda::RodaError: unsupported block result: {:data=>{:add=>6, :multiply=>8}}
/usr/local/rvm/gems/default/gems/roda-3.62.0/lib/roda/request.rb:550:in `block_result_body'
/usr/local/rvm/gems/default/gems/roda-3.62.0/lib/roda/request.rb:95:in `block_result'
/usr/local/rvm/gems/default/gems/roda-3.62.0/lib/roda/request.rb:603:in `if_match'
/usr/local/rvm/gems/default/gems/roda-3.62.0/lib/roda/request.rb:241:in `on'
using to_json
does work as expected, though.
# ... shortened
# /:int
r.on Integer do |x|
# /:int
r.on Integer do |y|
{ data: {add: x + y,
multiply: x * y} }.to_json
end
end
# ... shortened
Thank you very much for posting a reproducible example. This turns out not to be a Roda issue. What happens is that rack-unreloader unloads all constants added by the require 'app.rb'
call, which is much more than App
. One way to see the problem is to add a rack-unreloader logger:
require 'logger'
Unreloader = Rack::Unreloader.new(:logger=>Logger.new($stdout)){App}
That shows the problem. When you modify the app.rb
file, it unloads a bunch of constants you don't want it to unload. You can fix the problem by specifying which constants to unload when the app.rb
file changes:
Unreloader.require('app.rb'){:App}
The rack-unreloader README discusses this issue, please see:
- https://github.com/jeremyevans/rack-unreloader#label-Handling+Subclasses
- https://github.com/jeremyevans/rack-unreloader#label-Speeding+Things+Up
It would be nice if there was a better default behavior for rack-unreloader, but unfortunately I cannot think of one that doesn't involve modifying core methods such as require, which explicitly is against rack-unreloader's design.
Thank you so much for giving direction!
I was able to have hot reloading working with plugin :hash_routes
, finally. Took some inspiration from the code in roda-sequel-stack, too!