fix: Sanitize query canceled API errors (#14933)
# Pull Request Template ## Description Message creation API failures caused by PostgreSQL query cancellations now return a generic retryable error instead of exposing raw database internals such as `PG::QueryCanceled`, tuple identifiers, or relation names to customers. Existing validation failures continue to return their specific validation messages. Closes [CW-7538](https://linear.app/chatwoot/issue/CW-7538/do-not-expose-pgquerycanceled-details-in-messages-api-errors) ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Reproduced the messages API path by raising `ActiveRecord::QueryCanceled` from `Messages::MessageBuilder` and verified the response contains the customer-safe localized error without `PG::QueryCanceled` details. Validation run locally: - `bundle exec rspec spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb` - `bundle exec rubocop app/controllers/concerns/request_exception_handler.rb spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb` - `git diff --check` ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules
This commit is contained in:
@@ -51,6 +51,22 @@ RSpec.describe 'Conversation Messages API', type: :request do
|
||||
expect(json_response['error']).to eq('Validation failed: Content is too long (maximum is 150000 characters)')
|
||||
end
|
||||
|
||||
it 'returns a customer-safe error when the database query is canceled' do
|
||||
message_builder = instance_double(Messages::MessageBuilder)
|
||||
allow(Messages::MessageBuilder).to receive(:new).and_return(message_builder)
|
||||
allow(message_builder).to receive(:perform)
|
||||
.and_raise(ActiveRecord::QueryCanceled, 'PG::QueryCanceled: ERROR: canceling statement due to statement timeout')
|
||||
|
||||
post api_v1_account_conversation_messages_url(account_id: account.id, conversation_id: conversation.display_id),
|
||||
params: { content: 'test-message', private: true },
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
expect(response.parsed_body['error']).to eq(I18n.t('errors.database.query_canceled'))
|
||||
expect(response.parsed_body['error']).not_to include('PG::QueryCanceled')
|
||||
end
|
||||
|
||||
it 'creates an outgoing text message with a specific bot sender' do
|
||||
agent_bot = create(:agent_bot)
|
||||
time_stamp = Time.now.utc.to_s
|
||||
|
||||
Reference in New Issue
Block a user