fix(whatsapp): harden health sync failure handling

This commit is contained in:
Muhsin
2026-07-22 11:20:05 +04:00
parent a2b7a11b6c
commit ded86b9ed1
7 changed files with 52 additions and 7 deletions
@@ -587,7 +587,6 @@ export default {
this.healthData = response.data;
} catch (error) {
const apiError = error.response?.data?.error;
this.healthData = null;
this.healthError =
typeof apiError === 'object'
? apiError
@@ -335,11 +335,17 @@ const handleGoToSettings = () => {
const getQualityRatingTextColor = rating =>
QUALITY_COLORS[rating] || QUALITY_COLORS.UNKNOWN;
const formatTierDisplay = tier =>
t(`INBOX_MGMT.ACCOUNT_HEALTH.VALUES.TIERS.${tier}`) || tier;
const formatTierDisplay = tier => {
const translationKey = `INBOX_MGMT.ACCOUNT_HEALTH.VALUES.TIERS.${tier}`;
const formatModeDisplay = mode =>
t(`INBOX_MGMT.ACCOUNT_HEALTH.VALUES.MODES.${mode}`) || mode;
return te(translationKey) ? t(translationKey) : formatStatusDisplay(tier);
};
const formatModeDisplay = mode => {
const translationKey = `INBOX_MGMT.ACCOUNT_HEALTH.VALUES.MODES.${mode}`;
return te(translationKey) ? t(translationKey) : formatStatusDisplay(mode);
};
const getModeStatusTextColor = mode => MODE_COLORS[mode] || 'text-n-slate-12';
@@ -50,4 +50,20 @@ describe('AccountHealth', () => {
'_blank'
);
});
it('formats unknown messaging tiers and account modes without exposing translation keys', () => {
const wrapper = mountComponent({
messaging_limit_tier: 'TIER_CUSTOM',
account_mode: 'CUSTOM_MODE',
});
expect(wrapper.text()).toContain('Tier Custom');
expect(wrapper.text()).toContain('Custom Mode');
expect(wrapper.text()).not.toContain(
'INBOX_MGMT.ACCOUNT_HEALTH.VALUES.TIERS.TIER_CUSTOM'
);
expect(wrapper.text()).not.toContain(
'INBOX_MGMT.ACCOUNT_HEALTH.VALUES.MODES.CUSTOM_MODE'
);
});
});
@@ -3,5 +3,7 @@ class Channels::Whatsapp::HealthSyncJob < ApplicationJob
def perform(whatsapp_channel)
Whatsapp::HealthService.new(whatsapp_channel).sync_health_status!
rescue Whatsapp::HealthService::ApiError, ArgumentError
nil
end
end
@@ -2,7 +2,7 @@ class AddPhoneNumberHealthToChannelWhatsapp < ActiveRecord::Migration[7.1]
def change
add_column :channel_whatsapp, :phone_number_health, :jsonb, default: {}, null: false
add_column :channel_whatsapp, :phone_number_health_checked_at, :datetime
add_column :channel_whatsapp, :phone_number_health_error, :string
add_column :channel_whatsapp, :phone_number_health_error, :string, limit: 500
add_index :channel_whatsapp, :phone_number_health_checked_at
end
end
+1 -1
View File
@@ -685,7 +685,7 @@ ActiveRecord::Schema[7.1].define(version: 2026_07_18_000000) do
t.datetime "message_templates_last_updated", precision: nil
t.jsonb "phone_number_health", default: {}, null: false
t.datetime "phone_number_health_checked_at"
t.string "phone_number_health_error"
t.string "phone_number_health_error", limit: 500
t.index ["phone_number_health_checked_at"], name: "index_channel_whatsapp_on_phone_number_health_checked_at"
t.index ["phone_number"], name: "index_channel_whatsapp_on_phone_number", unique: true
end
@@ -23,4 +23,26 @@ RSpec.describe Channels::Whatsapp::HealthSyncJob do
expect(health_service).to have_received(:sync_health_status!)
end
it 'does not retry recorded API failures' do
error = Whatsapp::HealthService::ApiError.new(message: 'Request failed', http_status: 400)
allow(Whatsapp::HealthService).to receive(:new).with(whatsapp_channel).and_return(health_service)
allow(health_service).to receive(:sync_health_status!).and_raise(error)
expect { described_class.perform_now(whatsapp_channel) }.not_to raise_error
end
it 'does not retry recorded configuration failures' do
allow(Whatsapp::HealthService).to receive(:new).with(whatsapp_channel).and_return(health_service)
allow(health_service).to receive(:sync_health_status!).and_raise(ArgumentError, 'API key is missing')
expect { described_class.perform_now(whatsapp_channel) }.not_to raise_error
end
it 'retries unexpected failures' do
allow(Whatsapp::HealthService).to receive(:new).with(whatsapp_channel).and_return(health_service)
allow(health_service).to receive(:sync_health_status!).and_raise(StandardError, 'Database unavailable')
expect { described_class.perform_now(whatsapp_channel) }.to raise_error(StandardError, 'Database unavailable')
end
end