Skip to content

Commit dd303ea

Browse files
authored
Prevent the reuse of the event payload (baserow#4976)
1 parent 8c25ef6 commit dd303ea

File tree

5 files changed

+77
-27
lines changed

5 files changed

+77
-27
lines changed

backend/src/baserow/contrib/automation/nodes/node_types.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,16 @@ def on_event(
369369
for trigger in triggers:
370370
# If we've received a callable payload, call it with the specific service,
371371
# this can give us a payload that is specific to the trigger's service.
372-
if callable(event_payload):
373-
event_payload = event_payload(service_map[trigger.service_id])
372+
service_payload = (
373+
event_payload(service_map[trigger.service_id])
374+
if callable(event_payload)
375+
else event_payload
376+
)
374377

375378
workflow = trigger.workflow
376379
AutomationWorkflowHandler().async_start_workflow(
377380
workflow,
378-
event_payload,
381+
service_payload,
379382
)
380383

381384
# We don't want subsequent events to trigger a new test run

backend/src/baserow/contrib/integrations/core/utils.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,26 @@ def calculate_next_periodic_run(
7676
next_run = next_run.replace(hour=hour, minute=minute)
7777

7878
elif interval == PERIODIC_INTERVAL_MONTH:
79-
# Run at the specified day_of_month at hour:minute each month
80-
next_run = from_time.replace(day=day_of_month, hour=hour, minute=minute)
79+
# Run at the specified day_of_month at hour:minute each month.
80+
# Handle case where day_of_month doesn't exist in the current month
81+
# (e.g., day 30 in February) by using the last day of the month.
82+
try:
83+
next_run = from_time.replace(day=day_of_month, hour=hour, minute=minute)
84+
except ValueError:
85+
# Use last day of the current month
86+
next_run = from_time.replace(day=1) + relativedelta(months=1, days=-1)
87+
next_run = next_run.replace(hour=hour, minute=minute)
8188

8289
# If we've already passed this time this month, move to next month
8390
if next_run <= from_time:
84-
# Move to next month
8591
next_run += relativedelta(months=1)
86-
87-
# Handle case where day_of_month doesn't exist in the target month
88-
# (e.g., day 31 in February)
89-
try:
90-
next_run = next_run.replace(day=day_of_month)
91-
except ValueError:
92-
# If the day doesn't exist, use the last day of the month
93-
next_run = next_run.replace(day=1) + relativedelta(months=1, days=-1)
94-
next_run = next_run.replace(hour=hour, minute=minute)
92+
# Handle case where day_of_month doesn't exist in the target month
93+
try:
94+
next_run = next_run.replace(day=day_of_month)
95+
except ValueError:
96+
# Use last day of the target month
97+
next_run = next_run.replace(day=1) + relativedelta(months=1, days=-1)
98+
next_run = next_run.replace(hour=hour, minute=minute)
9599

96100
else:
97101
# Unknown interval type, default to 1 hour from now

backend/src/baserow/contrib/integrations/migrations/0026_backfill_coreperiodicservice_next_run_at.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,26 @@ def _calculate_next_run(interval, minute, hour, day_of_week, day_of_month, from_
5050
next_run = next_run.replace(hour=hour, minute=minute)
5151

5252
elif interval == "MONTH":
53-
# Run at the specified day_of_month at hour:minute each month
54-
next_run = from_time.replace(day=day_of_month, hour=hour, minute=minute)
53+
# Run at the specified day_of_month at hour:minute each month.
54+
# Handle case where day_of_month doesn't exist in the current month
55+
# (e.g., day 30 in February) by using the last day of the month.
56+
try:
57+
next_run = from_time.replace(day=day_of_month, hour=hour, minute=minute)
58+
except ValueError:
59+
# Use last day of the current month
60+
next_run = from_time.replace(day=1) + relativedelta(months=1, days=-1)
61+
next_run = next_run.replace(hour=hour, minute=minute)
5562

5663
# If we've already passed this time this month, move to next month
5764
if next_run <= from_time:
58-
# Move to next month
5965
next_run += relativedelta(months=1)
60-
61-
# Handle case where day_of_month doesn't exist in the target month
62-
# (e.g., day 31 in February)
63-
try:
64-
next_run = next_run.replace(day=day_of_month)
65-
except ValueError:
66-
# If the day doesn't exist, use the last day of the month
67-
next_run = next_run.replace(day=1) + relativedelta(months=1, days=-1)
68-
next_run = next_run.replace(hour=hour, minute=minute)
66+
# Handle case where day_of_month doesn't exist in the target month
67+
try:
68+
next_run = next_run.replace(day=day_of_month)
69+
except ValueError:
70+
# Use last day of the target month
71+
next_run = next_run.replace(day=1) + relativedelta(months=1, days=-1)
72+
next_run = next_run.replace(hour=hour, minute=minute)
6973

7074
else:
7175
# Unknown interval type, default to 1 hour from now

backend/tests/baserow/contrib/integrations/core/cases/core_periodic_service_type.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,36 @@
507507
datetime(2025, 2, 15, 10, 0, 0, tzinfo=timezone.utc),
508508
datetime(2025, 3, 1, 0, 0, 0, tzinfo=timezone.utc),
509509
),
510+
# Day doesn't exist in current month (e.g., Feb 30th)
511+
(
512+
PERIODIC_INTERVAL_MONTH,
513+
30,
514+
14,
515+
0,
516+
30, # Day 30 doesn't exist in February
517+
datetime(2025, 2, 10, 10, 0, 0, tzinfo=timezone.utc), # Currently Feb 10th
518+
datetime(2025, 2, 28, 14, 30, 0, tzinfo=timezone.utc), # Falls back to Feb 28th
519+
),
520+
# Day doesn't exist in current month and time has passed (move to next month)
521+
(
522+
PERIODIC_INTERVAL_MONTH,
523+
30,
524+
14,
525+
0,
526+
30, # Day 30 doesn't exist in February
527+
datetime(2025, 2, 28, 15, 0, 0, tzinfo=timezone.utc), # After 14:30 on Feb 28th
528+
datetime(2025, 3, 30, 14, 30, 0, tzinfo=timezone.utc), # March 30th exists
529+
),
530+
# Day doesn't exist in current or next month (Feb -> Mar with day 31)
531+
(
532+
PERIODIC_INTERVAL_MONTH,
533+
30,
534+
14,
535+
0,
536+
31, # Day 31
537+
datetime(2025, 2, 10, 10, 0, 0, tzinfo=timezone.utc), # Currently Feb 10th
538+
datetime(2025, 2, 28, 14, 30, 0, tzinfo=timezone.utc), # Falls back to Feb 28th
539+
),
510540
]
511541

512542
PERIODIC_SERVICE_NEXT_RUN_SET_CASES = [
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "bug",
3+
"message": "Resolved a bug in the periodic trigger which prevented it from being scheduled correctly.",
4+
"issue_origin": "github",
5+
"issue_number": null,
6+
"domain": "integration",
7+
"bullet_points": [],
8+
"created_at": "2026-03-13"
9+
}

0 commit comments

Comments
 (0)