fix(test-dispatch): fall back to tracker defaults, surface soft errors
- dispatch_test_notification now resolves tracking_config / template_config
from the tracker's default_* fields when the per-link override is unset,
matching what load_link_data does for the real watcher. Previously
periodic/scheduled/memory tests silently failed with "no template
defined" whenever the user configured the template config at the
tracker level instead of on each link (the UI's normal default).
- Distinguish the two missing-template cases in the returned error
("no template config linked" vs. "slot missing in linked config").
- Frontend testTrackerTarget now treats {success:false,error:"..."} in a
2xx body as a failure — previously any 2xx flashed a success snack so
users never saw the real reason their test didn't deliver.
This commit is contained in:
@@ -358,8 +358,19 @@
|
||||
if (ttTesting[key]) return;
|
||||
ttTesting = { ...ttTesting, [key]: testType };
|
||||
try {
|
||||
await api(`/notification-trackers/${trackerId}/targets/${ttId}/test/${testType}?locale=${getLocale()}`, { method: 'POST' });
|
||||
snackSuccess(t('snack.targetTestSent'));
|
||||
// The endpoint returns 200 OK with ``{success: false, error: "..."}``
|
||||
// on soft failures (missing template slot, no matching assets,
|
||||
// provider unreachable, etc.), so checking for a thrown exception
|
||||
// is not enough. Surface ``error`` as a snackError when present.
|
||||
const res = await api<{ success?: boolean; error?: string; target?: string }>(
|
||||
`/notification-trackers/${trackerId}/targets/${ttId}/test/${testType}?locale=${getLocale()}`,
|
||||
{ method: 'POST' },
|
||||
);
|
||||
if (res && res.success === false) {
|
||||
snackError(res.error || t('common.error'));
|
||||
} else {
|
||||
snackSuccess(t('snack.targetTestSent'));
|
||||
}
|
||||
} catch (err: any) {
|
||||
snackError(err.message);
|
||||
} finally {
|
||||
|
||||
@@ -55,17 +55,21 @@ async def dispatch_test_notification(
|
||||
provider_config = dict(provider.config)
|
||||
collection_ids = list(tracker.collection_ids or [])
|
||||
|
||||
# Load tracking config
|
||||
# Resolve tracking config: per-link override, else the tracker's default.
|
||||
# The real watcher applies this fallback in ``load_link_data`` — tests
|
||||
# must use the same logic or the user's per-tracker defaults look broken.
|
||||
tracking_config_id = tt.tracking_config_id or tracker.default_tracking_config_id
|
||||
tracking_config = None
|
||||
if tt.tracking_config_id:
|
||||
tracking_config = await session.get(TrackingConfig, tt.tracking_config_id)
|
||||
if tracking_config_id:
|
||||
tracking_config = await session.get(TrackingConfig, tracking_config_id)
|
||||
|
||||
# Load template slots keyed by EventType.SCHEDULED_MESSAGE.value
|
||||
# Same fallback for template config.
|
||||
template_config_id = tt.template_config_id or tracker.default_template_config_id
|
||||
template_config = None
|
||||
template_slots: dict[str, dict[str, str]] | None = None
|
||||
slot_name = _TEST_TYPE_SLOT_MAP.get(test_type, test_type)
|
||||
if tt.template_config_id:
|
||||
template_config = await session.get(TemplateConfig, tt.template_config_id)
|
||||
if template_config_id:
|
||||
template_config = await session.get(TemplateConfig, template_config_id)
|
||||
if template_config:
|
||||
slot_result = await session.exec(
|
||||
select(TemplateSlot).where(
|
||||
@@ -97,10 +101,21 @@ async def dispatch_test_notification(
|
||||
)
|
||||
|
||||
if not template_slots:
|
||||
if not template_config_id:
|
||||
return {
|
||||
"success": False,
|
||||
"error": (
|
||||
"This tracker has no Template Config linked (neither on the "
|
||||
"tracker's default nor on this target link). Assign one in the "
|
||||
"tracker settings and make sure it defines a "
|
||||
f"'{slot_name}' slot."
|
||||
),
|
||||
}
|
||||
return {
|
||||
"success": False,
|
||||
"error": (
|
||||
f"No '{slot_name}' template defined for this target's template config "
|
||||
f"No '{slot_name}' template defined in the linked Template Config "
|
||||
f"'{template_config.name if template_config else template_config_id}' "
|
||||
f"(locale: {locale}). Add the slot under Template Configs."
|
||||
),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user