From 73e29e2585d1d1223cf74d412d5fed2aea8cb3bf Mon Sep 17 00:00:00 2001 From: Stefan Hammer Date: Thu, 13 Jul 2023 09:15:02 +0200 Subject: [PATCH] Add error logging to the timestamp migration and improved migration This also changes the migration of items with 2 timestamps, so it still migrates the valid one, if the other is invalid. See #9590 --- .../0088_fix_log_entry_json_timestamps.py | 49 ++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/wagtail/migrations/0088_fix_log_entry_json_timestamps.py b/wagtail/migrations/0088_fix_log_entry_json_timestamps.py index 227eacf5c9d7..db0c79feb704 100644 --- a/wagtail/migrations/0088_fix_log_entry_json_timestamps.py +++ b/wagtail/migrations/0088_fix_log_entry_json_timestamps.py @@ -1,12 +1,15 @@ # Generated by Django 3.2.6 on 2022-11-09 07:50 import datetime +import logging import django.core.serializers.json from django.conf import settings from django.db import migrations, models from django.utils import timezone, dateparse +logger = logging.getLogger("wagtail.migrations") + def legacy_to_iso_format(date_string, tz=None): dt = datetime.datetime.strptime(date_string, "%d %b %Y %H:%M") @@ -43,7 +46,13 @@ def migrate_logs_with_created_only(model, converter): # to UTC by django. item.data["revision"]["created"] = converter(created) except ValueError: - # TODO TBD: log error? + logger.warning( + "Failed to migrate 'created' timestamp '%s' of %s %s (%s)", + item.data["revision"]["created"], + model.__name__, + item.pk, + converter.__name__, + ) continue except KeyError: continue @@ -62,24 +71,42 @@ def migrate_schedule_logs(model, converter): created = item.data["revision"]["created"] # May be unset for "wagtail.schedule.cancel"-logs. go_live_at = item.data["revision"].get("go_live_at") + changed = False try: # "created" is set to timezone.now() for new revisions ("wagtail.publish.schedule") # and to self.created_at for "wagtail.schedule.cancel", which is set to UTC # by django. item.data["revision"]["created"] = converter(created) - - if go_live_at: - # The go_live_at date is set to the revision object's "go_live_at". - # The revision's object is created by deserializing the json data (see wagtail.models.Revision.as_object()), - # and this process converts all datetime objects to the local timestamp (see https://github.com/wagtail/django-modelcluster/blob/8666f16eaf23ca98afc160b0a4729864411c0563/modelcluster/models.py#L109-L115). - # That's the reason, why this date is the only date, which is not stored in the log's JSON as UTC, but in the default timezone. + changed = True + except ValueError: + logger.warning( + "Failed to migrate 'created' timestamp '%s' of %s %s (%s)", + created, + model.__name__, + item.pk, + converter.__name__, + ) + + if go_live_at: + # The go_live_at date is set to the revision object's "go_live_at". + # The revision's object is created by deserializing the json data (see wagtail.models.Revision.as_object()), + # and this process converts all datetime objects to the local timestamp (see https://github.com/wagtail/django-modelcluster/blob/8666f16eaf23ca98afc160b0a4729864411c0563/modelcluster/models.py#L109-L115). + # That's the reason, why this date is the only date, which is not stored in the log's JSON as UTC, but in the default timezone. + try: item.data["revision"]["go_live_at"] = converter( go_live_at, tz=timezone.get_default_timezone() ) - except ValueError: - # TODO TBD: log error? - continue - else: + changed = True + except ValueError: + logger.warning( + "Failed to migrate 'go_live_at' timestamp '%s' of %s %s (%s)", + go_live_at, + model.__name__, + item.pk, + converter.__name__, + ) + + if changed: item.save(update_fields=["data"])