fix(whatsapp): harden health sync failure handling
This commit is contained in:
@@ -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
|
||||
|
||||
+10
-4
@@ -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';
|
||||
|
||||
|
||||
+16
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user