Repository: bookwyrm-social/bookwyrm

Issue:
Connector fails to load book when a openlibrary text field is too long
via Celery, in load_more_data:
```
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(255)


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/app/bookwyrm/books_manager.py", line 64, in load_more_data
    connector.expand_book_data(book)
  File "/app/bookwyrm/connectors/openlibrary.py", line 167, in expand_book_data
    edition = self.create_book(olkey, edition_data, models.Edition)
  File "/app/bookwyrm/connectors/abstract_connector.py", line 155, in create_book
    return self.update_book_from_data(book, data)
  File "/app/bookwyrm/connectors/abstract_connector.py", line 168, in update_book_from_data
    book.save()
  File "/app/bookwyrm/models/book.py", line 202, in save
    super().save(*args, **kwargs)
  File "/app/bookwyrm/models/book.py", line 116, in save
    super().save(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 745, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 781, in save_base
    parent_inserted = self._save_parents(cls, using, update_fields)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 810, in _save_parents
    updated = self._save_table(
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 864, in _save_table
    updated = self._do_update(base_qs, using, pk_val, values, update_fields,
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 917, in _do_update
    return filtered._update(values) > 0
  File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 771, in _update
    return query.get_compiler(self.db).execute_sql(CURSOR)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1500, in execute_sql
    cursor = super().execute_sql(result_type)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1152, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.DataError: value too long for type character varying(255)
```


Discussion:
Do you know what openlibrary book caused this? I could help debug / write a test for that.
No, unfortunately. It could be anything with a particularly long title or subtitle, though

Resolving patch:
diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py
--- a/bookwyrm/connectors/abstract_connector.py
+++ b/bookwyrm/connectors/abstract_connector.py
@@ -179,7 +179,11 @@ def get_or_create_author(self, remote_id):
         data = get_data(remote_id)
 
         mapped_data = dict_from_mappings(data, self.author_mappings)
-        activity = activitypub.Author(**mapped_data)
+        try:
+            activity = activitypub.Author(**mapped_data)
+        except activitypub.ActivitySerializerError:
+            return None
+
         # this will dedupe
         return activity.to_model(model=models.Author)
 
diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py
--- a/bookwyrm/connectors/openlibrary.py
+++ b/bookwyrm/connectors/openlibrary.py
@@ -93,7 +93,10 @@ def get_authors_from_data(self, data):
             # this id is "/authors/OL1234567A"
             author_id = author_blob["key"]
             url = "%s%s" % (self.base_url, author_id)
-            yield self.get_or_create_author(url)
+            author = self.get_or_create_author(url)
+            if not author:
+                continue
+            yield author
 
     def get_cover_url(self, cover_blob, size="L"):
         """ ask openlibrary for the cover """
diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py
--- a/bookwyrm/models/book.py
+++ b/bookwyrm/models/book.py
@@ -53,14 +53,14 @@ class Book(BookDataModel):
     connector = models.ForeignKey("Connector", on_delete=models.PROTECT, null=True)
 
     # book/work metadata
-    title = fields.CharField(max_length=255)
+    title = fields.TextField(max_length=255)
     sort_title = fields.CharField(max_length=255, blank=True, null=True)
-    subtitle = fields.CharField(max_length=255, blank=True, null=True)
+    subtitle = fields.TextField(max_length=255, blank=True, null=True)
     description = fields.HtmlField(blank=True, null=True)
     languages = fields.ArrayField(
         models.CharField(max_length=255), blank=True, default=list
     )
-    series = fields.CharField(max_length=255, blank=True, null=True)
+    series = fields.TextField(max_length=255, blank=True, null=True)
     series_number = fields.CharField(max_length=255, blank=True, null=True)
     subjects = fields.ArrayField(
         models.CharField(max_length=255), blank=True, null=True, default=list


Test patch: