Skip to content

Conversation

@alassek
Copy link
Contributor

@alassek alassek commented Oct 25, 2025

Rack 3 changed the symbolic name of 422 from :unprocessable_entity to :unprocessable_content.

This follows from the rename in the HTTP spec. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/422

SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE
SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE.dup

if Gem.loaded_specs["rack"].version.version.start_with?("3")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplest way I could think to determine this with a minimum of allocations

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking we could just use Rack::VERSION to check against rather than dropping this far, but rack 2's version const is... weird.

I think I might change that second version call for to_s as Gem::Version does respond with a string version

Gem.loaded_specs["rack"].version.to_s.start_with?("3")
± be hanami console
forked[development]> Gem.loaded_specs["rack"].version.to_s.start_with?("3")
=> true
forked[development]> Gem.loaded_specs["rack"].version.to_s
=> "3.2.3"

and in rack 2

± be hanami console
forked[development]> Rack::VERSION
=> [1, 3]
forked[development]> Rack
=> Rack
forked[development]> Rack::VERSION.to_s
=> "[1, 3]"
forked[development]> Gem.loaded_specs["rack"].version.version
=> "2.2.20"
forked[development]> Gem.loaded_specs["rack"].version
=> Gem::Version.new("2.2.20")
forked[development]> Gem.loaded_specs["rack"].version.to_s
=> "2.2.20"
forked[development]> Gem.loaded_specs["rack"].version.to_s
=> "2.2.20"
forked[development]> Gem.loaded_specs["rack"].version.class
=> Gem::Version
forked[development]> Gem.loaded_specs["rack"].version.version
=> "2.2.20"
forked[development]> Gem.loaded_specs["rack"].version.to_s
=> "2.2.20"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gem::Version#to_s appears to be an alias to #version

Copy link
Member

@timriley timriley Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a simple check for this that you can reuse: Hanami::Action.rack_3? See lib/hanami/action/rack_utils.rb and feel free to grep for it across the repo to see how we use it.

That said, based on my comment below, we may no longer need a Rack version check for this PR.

@alassek alassek requested a review from timriley October 25, 2025 21:09
if Gem.loaded_specs["rack"].version.version.start_with?("3")
SYMBOLS[:unprocessable_entity] = 422
else
SYMBOLS[:unprocessable_content] = 422
Copy link
Member

@aaronmallen aaronmallen Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we feel about keeping :unprocessable_entity in addition to the new symbol for backwards compatibility?

Copy link
Member

@timriley timriley Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that because we've documented unprocessable_entity, it would be good for us to maintain it in the future.

I think for our 2.3 docs, we should show both unprocessable_content and unprocessable_content as working for 422, and should update this PR to work with both, for either version of Rack.

This feels important during this Rack v2/v3 transitional phase, which I expect we might keep for ~a year or so.

I think this might also simplify this PR? We'd just merge unprocessable_content and unprocessable_content keys into our SYMBOLS hash regardless of the version of rack we see being used?

Copy link
Member

@timriley timriley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for doing this, @alassek! This will take away one little hitch for our users and hopefully make their upgrade nicer :)

I've left a thought via a comment about a change in approach. Keen to hear what you think.

SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE
SYMBOLS = ::Rack::Utils::SYMBOL_TO_STATUS_CODE.dup

if Gem.loaded_specs["rack"].version.version.start_with?("3")
Copy link
Member

@timriley timriley Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a simple check for this that you can reuse: Hanami::Action.rack_3? See lib/hanami/action/rack_utils.rb and feel free to grep for it across the repo to see how we use it.

That said, based on my comment below, we may no longer need a Rack version check for this PR.

if Gem.loaded_specs["rack"].version.version.start_with?("3")
SYMBOLS[:unprocessable_entity] = 422
else
SYMBOLS[:unprocessable_content] = 422
Copy link
Member

@timriley timriley Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that because we've documented unprocessable_entity, it would be good for us to maintain it in the future.

I think for our 2.3 docs, we should show both unprocessable_content and unprocessable_content as working for 422, and should update this PR to work with both, for either version of Rack.

This feels important during this Rack v2/v3 transitional phase, which I expect we might keep for ~a year or so.

I think this might also simplify this PR? We'd just merge unprocessable_content and unprocessable_content keys into our SYMBOLS hash regardless of the version of rack we see being used?

@alassek
Copy link
Contributor Author

alassek commented Oct 26, 2025

@timriley yep that's a cleaner approach, but good to know we have a helper for that.

I've also opened a documentation PR at hanami/guides#308

Copy link
Member

@timriley timriley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alassek, looks great!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever! 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Written originally for activerecord-pg_enum, I needed very fine-grained version distinction for my test suite

@alassek alassek merged commit 31b7383 into main Oct 26, 2025
14 checks passed
@alassek alassek deleted the http-status-422 branch October 26, 2025 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants