discourse/lib/reviewable/perform_result.rb
Alan Guo Xiang Tan 3324fe4fef
FIX: ensure remove_reviewable_ids is always an array (#37131)
What is the problem?

The review queue throws a JavaScript error when processing MessageBus
updates:

```
MESSAGE BUS FAIL: callback /reviewable_action caused exception
TypeError: Cannot read properties of undefined (reading 'includes')
```

The bug flow is:

1. `Reviewable::PerformResult#initialize` only sets
`@remove_reviewable_ids`
   when `success?` is true, leaving it nil otherwise
2. `ReviewablePerformResultSerializer` serializes nil as JSON null
3. MessageBus publishes this to `/reviewable_action` channel
4. The JS `_updateStatus` callback in `ReviewableItem` receives data
with
   `remove_reviewable_ids` as null/undefined
5. Calling `.includes()` on null throws TypeError

What is the solution?

Always initialize `@remove_reviewable_ids` as an array in
`Reviewable::PerformResult#initialize` (empty for failures, containing
the reviewable id for successes). Also add defensive optional chaining
in the JS `ReviewableItem#_updateStatus` callback and update the truthy
check in `ReviewableItem#_performResult` to verify array length since
`[]` is truthy in JavaScript.
2026-01-15 10:35:59 +08:00

32 lines
723 B
Ruby

# frozen_string_literal: true
class Reviewable < ActiveRecord::Base
class PerformResult
include ActiveModel::Serialization
attr_reader :reviewable, :status, :created_post, :created_post_topic
attr_accessor(
:transition_to,
:remove_reviewable_ids,
:errors,
:recalculate_score,
:update_flag_stats,
:after_commit,
)
def initialize(reviewable, status)
@status = status
@reviewable = reviewable
@remove_reviewable_ids = success? ? [reviewable.id] : []
end
def created_post=(created_post)
@created_post = created_post
@created_post_topic = created_post.topic
end
def success?
@status == :success
end
end
end