diff --git a/config.py.example b/config.py.example
index d23beb8f7ffb7567deb7c8a8b3ae8f782aa46603..581ca2258cc1f74ba69b02a9fdcafc4f7e33565d 100644
--- a/config.py.example
+++ b/config.py.example
@@ -196,7 +196,7 @@ LATEX_BULLETPOINTS = [
 #        "logo": "asta-logo.tex", # optional: replaces the general template to include at the top of protocol.tex set by LATEX_LOGO_TEMPLATE
 #        "geometry": "bottom=1.6cm,top=1.6cm,inner=2.5cm,outer=1.0cm,footskip=1.0cm,headsep=0.6cm", # optional: replaces the general protocol page geometry set by LATEX_GEOMETRY
 #        "pagestyle": "fancy", # optional: replaces the general protocol pagestyle set by LATEX_PAGESTYLE
-#        "additionalpackages": ["[absolute]{textpos}", "{fancyheadings}"], # optional: replaces the general latex packages set by LATEX_ADDITIONAL_PACKAGES
+#        "additional_packages": ["[absolute]{textpos}", "{fancyheadings}"], # optional: replaces the general latex packages set by LATEX_ADDITIONAL_PACKAGES
 #        "headerfooter": True # optional: replaces the general LATEX_HEADER_FOOTER option
 #    }
 #}
diff --git a/tasks.py b/tasks.py
index 852c3b48b565e716c1bcf8a44308e9562996abda..50d047684b23ee32a6e22e8cf71414cd8f05d8ba 100644
--- a/tasks.py
+++ b/tasks.py
@@ -9,15 +9,21 @@ import traceback
 from copy import copy
 import xmlrpc.client
 
-from models.database import Document, Protocol, Error, Todo, Decision, TOP, DefaultTOP, MeetingReminder, TodoMail, DecisionDocument, TodoState, OldTodo, DecisionCategory
+from models.database import (
+    Document, Protocol, Todo, Decision, TOP, MeetingReminder,
+    TodoMail, DecisionDocument, TodoState, OldTodo, DecisionCategory)
 from models.errors import DateNotMatchingException
 from server import celery, app
-from shared import db, escape_tex, unhyphen, date_filter, datetime_filter, date_filter_long, date_filter_short, time_filter, class_filter, KNOWN_KEYS, WikiType
-from utils import mail_manager, encode_kwargs, decode_kwargs, add_line_numbers, set_etherpad_text, get_etherpad_text, footnote_hash, parse_datetime_from_string
-from protoparser import parse, ParserException, Element, Content, Text, Tag, Remark, Fork, RenderType
+from shared import (
+    db, escape_tex, unhyphen, date_filter, datetime_filter, date_filter_long,
+    date_filter_short, time_filter, class_filter, KNOWN_KEYS, WikiType)
+from utils import (
+    mail_manager, add_line_numbers,
+    set_etherpad_text, parse_datetime_from_string)
+from protoparser import parse, ParserException, Tag, Remark, Fork, RenderType
 from wiki import WikiClient, WikiException
 from calendarpush import Client as CalendarClient, CalendarException
-from legacy import lookup_todo_id, import_old_todos
+from legacy import lookup_todo_id
 
 import config
 
@@ -32,7 +38,6 @@ texenv.filters["escape_tex"] = escape_tex
 texenv.filters["unhyphen"] = unhyphen
 texenv.trim_blocks = True
 texenv.lstrip_blocks = True
-#texenv.filters["url_complete"] = url_manager.complete
 texenv.filters["datify"] = date_filter
 texenv.filters["datify_long"] = date_filter_long
 texenv.filters["datify_short"] = date_filter_short
@@ -42,7 +47,9 @@ texenv.filters["class"] = class_filter
 logo_template = getattr(config, "LATEX_LOGO_TEMPLATE", None)
 if logo_template is not None:
     texenv.globals["logo_template"] = logo_template
-latex_geometry = getattr(config, "LATEX_GEOMETRY", "vmargin=1.5cm,hmargin={1.5cm,1.2cm},bindingoffset=8mm")
+latex_geometry = getattr(
+    config, "LATEX_GEOMETRY",
+    "vmargin=1.5cm,hmargin={1.5cm,1.2cm},bindingoffset=8mm")
 texenv.globals["latex_geometry"] = latex_geometry
 raw_additional_packages = getattr(config, "LATEX_ADDITIONAL_PACKAGES", None)
 additional_packages = []
@@ -59,51 +66,67 @@ latex_header_footer = getattr(config, "LATEX_HEADER_FOOTER", False)
 texenv.globals["latex_header_footer"] = latex_header_footer
 latex_templates = getattr(config, "LATEX_TEMPLATES", None)
 
+
 def provide_latex_template(template, documenttype):
-	_latex_template_documenttype_filename = {
-		"class": "protokoll2.cls",
-		"protocol": "protocol.tex",
-		"decision": "decision.tex"
-	}
-	_latex_template_filename = _latex_template_documenttype_filename[documenttype]
-	_latex_template_foldername = ""
-	if logo_template is not None:
-		texenv.globals["logo_template"] = logo_template
-	texenv.globals["latex_geometry"] = latex_geometry
-	texenv.globals["additional_packages"] = additional_packages
-	if latex_pagestyle is not None and latex_pagestyle:
-		texenv.globals["latex_pagestyle"] = latex_pagestyle
-	elif "latex_pagestyle" in texenv.globals:
-		del texenv.globals["latex_pagestyle"]
-	texenv.globals["latex_header_footer"] = latex_header_footer
-	if (latex_templates is not None) and (template is not ""):
-		if template in latex_templates:
-			if "provides" in latex_templates[template]:
-				_latex_template_foldername = (template + "/") if documenttype in latex_templates[template]["provides"] else ""
-			if "logo" in latex_templates[template]:
-				texenv.globals["logo_template"] = template + "/" + latex_templates[template]["logo"]
-			if "geometry" in latex_templates[template]:
-				texenv.globals["latex_geometry"] = latex_templates[template]["geometry"]
-			if "pagestyle" in latex_templates[template]:
-				if latex_templates[template]["pagestyle"]:
-					texenv.globals["latex_pagestyle"] = latex_templates[template]["pagestyle"]
-			if "additionalpackages" in latex_templates[template]:
-				_raw_additional_packages = latex_templates[template]["additionalpackages"]
-				_additional_packages = []
-				if _raw_additional_packages is not None:
-					for _package in _raw_additional_packages:
-						if "{" not in _package:
-							_package = "{{{}}}".format(_package)
-						_additional_packages.append(_package)
-				texenv.globals["additional_packages"] = _additional_packages	
-			if "headerfooter" in latex_templates[template]:
-				texenv.globals["latex_header_footer"] = latex_templates[template]["headerfooter"]
-	return _latex_template_foldername + _latex_template_filename
+    _DOCUMENTTYPE_FILENAME_MAP = {
+        "class": "protokoll2.cls",
+        "protocol": "protocol.tex",
+        "decision": "decision.tex"
+    }
+    _PROVIDES = "provides"
+    _LOGO_TEMPLATE = "logo_template"
+    _LOGO = "logo"
+    _LATEX_GEOMETRY = "latex_geometry"
+    _GEOMETRY = "geometry"
+    _ADDITIONAL_PACKAGES = "additional_packages"
+    _LATEX_PAGESTYLE = "latex_pagestyle"
+    _PAGESTYLE = "pagestyle"
+    _LATEX_HEADER_FOOTER = "latex_header_footer"
+    _HEADER_FOOTER = "headerfooter"
+    _latex_template_filename = _DOCUMENTTYPE_FILENAME_MAP[documenttype]
+    _latex_template_foldername = ""
+    if logo_template is not None:
+        texenv.globals[_LOGO_TEMPLATE] = logo_template
+    texenv.globals[_LATEX_GEOMETRY] = latex_geometry
+    texenv.globals[_ADDITIONAL_PACKAGES] = additional_packages
+    if latex_pagestyle:
+        texenv.globals[_LATEX_PAGESTYLE] = latex_pagestyle
+    elif _LATEX_PAGESTYLE in texenv.globals:
+        del texenv.globals[_LATEX_PAGESTYLE]
+    texenv.globals[_LATEX_HEADER_FOOTER] = latex_header_footer
+    if latex_templates is not None and template != "":
+        if template in latex_templates:
+            template_data = latex_templates[template]
+            if _PROVIDES in template_data:
+                if documenttype in template_data[_PROVIDES]:
+                    _latex_template_foldername = template
+            if _LOGO in template_data:
+                texenv.globals[_LOGO_TEMPLATE] = os.path.join(
+                    template, template_data[_LOGO])
+            if _GEOMETRY in template_data:
+                texenv.globals[_LATEX_GEOMETRY] = template_data[_GEOMETRY]
+            if _PAGESTYLE in template_data:
+                if template_data[_PAGESTYLE]:
+                    texenv.globals[_LATEX_PAGESTYLE] = (
+                        template_data[_PAGESTYLE])
+            if _ADDITIONAL_PACKAGES in template_data:
+                _raw_additional_packages = template_data[_ADDITIONAL_PACKAGES]
+                _additional_packages = []
+                if _raw_additional_packages is not None:
+                    for _package in _raw_additional_packages:
+                        if "{" not in _package:
+                            _package = "{{{}}}".format(_package)
+                        _additional_packages.append(_package)
+                texenv.globals[_ADDITIONAL_PACKAGES] = _additional_packages
+            if _HEADER_FOOTER in latex_templates[template]:
+                texenv.globals[_LATEX_HEADER_FOOTER] = (
+                    template_data[_HEADER_FOOTER])
+    return os.path.join(_latex_template_foldername, _latex_template_filename)
+
 
 mailenv = app.create_jinja_environment()
 mailenv.trim_blocks = True
 mailenv.lstrip_blocks = True
-#mailenv.filters["url_complete"] = url_manager.complete
 mailenv.filters["datify"] = date_filter
 mailenv.filters["datetimify"] = datetime_filter
 
@@ -124,43 +147,46 @@ wikienv.filters["timify"] = time_filter
 wikienv.filters["class"] = class_filter
 
 
+def _make_error(protocol, *args):
+    error = protocol.create_error(*args)
+    db.session.add(error)
+    db.session.commit()
+
+
 ID_FIELD_BEGINNING = "id "
 
-def parse_protocol(protocol, **kwargs):
-    parse_protocol_async.delay(protocol.id, encode_kwargs(kwargs))
+
+def parse_protocol(protocol):
+    parse_protocol_async.delay(protocol.id)
+
 
 @celery.task
-def parse_protocol_async(protocol_id, encoded_kwargs):
+def parse_protocol_async(protocol_id):
     with app.app_context():
         with app.test_request_context("/"):
             try:
-                kwargs = decode_kwargs(encoded_kwargs)
-                protocol = Protocol.query.filter_by(id=protocol_id).first()
+                protocol = Protocol.first_by_id(protocol_id)
                 if protocol is None:
                     raise Exception("No protocol given. Aborting parsing.")
-                parse_protocol_async_inner(protocol, encoded_kwargs)
+                parse_protocol_async_inner(protocol)
             except Exception as exc:
                 stacktrace = traceback.format_exc()
-                error = protocol.create_error("Parsing", "Exception",
+                return _make_error(
+                    protocol, "Parsing", "Exception",
                     "{}\n\n{}".format(str(exc), stacktrace))
-                db.session.add(error)
-                db.session.commit()
 
-def parse_protocol_async_inner(protocol, encoded_kwargs):
+
+def parse_protocol_async_inner(protocol):
     old_errors = list(protocol.errors)
     for error in old_errors:
         protocol.errors.remove(error)
     db.session.commit()
     if protocol.source is None or len(protocol.source.strip()) == 0:
-        error = protocol.create_error("Parsing", "Protocol source is empty", "")
-        db.session.add(error)
-        db.session.commit()
-        return
+        return _make_error(protocol, "Parsing", "Protocol source is empty", "")
     if protocol.source == config.EMPTY_ETHERPAD:
-        error = protocol.create_error("Parsing", "The etherpad is unmodified and does not contain a protocol.", protocol.source)
-        db.session.add(error)
-        db.session.commit()
-        return
+        return _make_error(
+            protocol, "Parsing", "The etherpad is unmodified and does not "
+            "contain a protocol.", protocol.source)
     tree = None
     try:
         tree = parse(protocol.source)
@@ -169,59 +195,64 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
         if exc.linenumber is not None:
             source_lines = protocol.source.splitlines()
             start_index = max(0, exc.linenumber - config.ERROR_CONTEXT_LINES)
-            end_index = min(len(source_lines) - 1, exc.linenumber + config.ERROR_CONTEXT_LINES)
+            end_index = min(
+                len(source_lines) - 1,
+                exc.linenumber + config.ERROR_CONTEXT_LINES)
             context = "\n".join(source_lines[start_index:end_index])
         if exc.tree is not None:
             context += "\n\nParsed syntax tree was:\n" + str(exc.tree.dump())
-        error = protocol.create_error("Parsing", str(exc), context)
-        db.session.add(error)
-        db.session.commit()
-        return
-    remarks = {element.name: element for element in tree.children if isinstance(element, Remark)}
+        return _make_error(protocol, "Parsing", str(exc), context)
+    remarks = {
+        element.name: element
+        for element in tree.children
+        if isinstance(element, Remark)
+    }
     required_fields = copy(KNOWN_KEYS)
     for default_meta in protocol.protocoltype.metas:
         required_fields.append(default_meta.key)
     if not config.PARSER_LAZY:
-        missing_fields = [field for field in required_fields if field not in remarks]
+        missing_fields = [
+            field
+            for field in required_fields
+            if field not in remarks
+        ]
         if len(missing_fields) > 0:
-            error = protocol.create_error("Parsing", "Du hast vergessen, Metadaten anzugeben.", ", ".join(missing_fields))
-            db.session.add(error)
-            db.session.commit()
-            return
+            return _make_error(
+                protocol, "Parsing", "Du hast vergessen, Metadaten anzugeben.",
+                ", ".join(missing_fields))
     try:
         protocol.fill_from_remarks(remarks)
     except ValueError:
-        error = protocol.create_error(
-            "Parsing", "Invalid fields",
+        return _make_error(
+            protocol, "Parsing", "Invalid fields",
             "Date or time fields are not '%d.%m.%Y' respectively '%H:%M', "
             "but rather {}".format(
-            ", ".join([
-                remarks["Datum"].value.strip(),
-                remarks["Beginn"].value.strip(),
-                remarks["Ende"].value.strip()
-            ])))
-        db.session.add(error)
-        db.session.commit()
-        return
+                ", ".join([
+                    remarks["Datum"].value.strip(),
+                    remarks["Beginn"].value.strip(),
+                    remarks["Ende"].value.strip()
+                ])))
     except DateNotMatchingException as exc:
-        error = protocol.create_error("Parsing", "Date not matching",
-            "This protocol's date should be {}, but the protocol source says {}.".format(date_filter(exc.original_date) if exc.original_date is not None else "not present", date_filter(exc.protocol_date) if exc.protocol_date is not None else "not present"))
-        db.session.add(error)
-        db.session.commit()
-        return
-    # tags 
+        return _make_error(
+            protocol, "Parsing", "Date not matching",
+            "This protocol's date should be {}, but the protocol source "
+            "says {}.".format(
+                date_filter(exc.original_date)
+                if exc.original_date is not None
+                else "not present",
+                date_filter(exc.protocol_date)
+                if exc.protocol_date is not None
+                else "not present"))
+    # tags
     tags = tree.get_tags()
-    elements = tree.get_visible_elements(show_private=True)
     public_elements = tree.get_visible_elements(show_private=False)
     for tag in tags:
         if tag.name not in Tag.KNOWN_TAGS:
-            error = protocol.create_error("Parsing", "Invalid tag",
+            return _make_error(
+                protocol, "Parsing", "Invalid tag",
                 "The tag in line {} has the kind '{}', which is "
                 "not defined. This is probably an error mit a missing "
                 "semicolon.".format(tag.linenumber, tag.name))
-            db.session.add(error)
-            db.session.commit()
-            return
     # todos
     old_todo_number_map = {}
     for todo in protocol.todos:
@@ -233,14 +264,12 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
     raw_todos = []
     for todo_tag in todo_tags:
         if len(todo_tag.values) < 2:
-            error = protocol.create_error("Parsing", "Invalid todo-tag",
+            return _make_error(
+                protocol, "Parsing", "Invalid todo-tag",
                 "The todo tag in line {} needs at least "
                 "information on who and what, "
                 "but has less than that. This is probably "
                 "a missing semicolon.".format(todo_tag.linenumber))
-            db.session.add(error)
-            db.session.commit()
-            return
         who = todo_tag.values[0]
         what = todo_tag.values[1]
         field_id = None
@@ -254,39 +283,45 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
                 try:
                     field_id = int(other_field[len(ID_FIELD_BEGINNING):])
                 except ValueError:
-                    error = protocol.create_error("Parsing", "Non-numerical todo ID",
-                    "The todo in line {} has a nonnumerical ID, but needs "
-                    "something like \"id 1234\"".format(todo_tag.linenumber))
-                    db.session.add(error)
-                    db.session.commit()
-                    return
+                    return _make_error(
+                        protocol, "Parsing", "Non-numerical todo ID",
+                        "The todo in line {} has a nonnumerical ID, but needs "
+                        "something like \"id 1234\"".format(
+                            todo_tag.linenumber))
             else:
                 try:
                     field_state = TodoState.from_name(other_field)
+                    continue
+                except ValueError:
+                    pass
+                try:
+                    field_date = datetime.strptime(other_field, "%d.%m.%Y")
+                    continue
                 except ValueError:
-                    try:
-                        field_date = datetime.strptime(other_field, "%d.%m.%Y")
-                    except ValueError:
-                        try:
-                            field_state, field_date = TodoState.from_name_with_date(other_field.strip(), protocol=protocol)
-                        except ValueError:
-                            try:
-                                field_state = TodoState.from_name_lazy(other_field)
-                            except ValueError:
-                                error = protocol.create_error("Parsing",
-                                "Invalid field",
-                                "The todo in line {} has the field '{}', but "
-                                "this does neither match a date (\"%d.%m.%Y\") "
-                                "nor a state.".format(
-                                    todo_tag.linenumber, other_field))
-                                db.session.add(error)
-                                db.session.commit()
-                                return
-        raw_todos.append((who, what, field_id, field_state, field_date, todo_tag))
+                    pass
+                try:
+                    field_state, field_date = TodoState.from_name_with_date(
+                        other_field.strip(), protocol=protocol)
+                    continue
+                except ValueError:
+                    pass
+                try:
+                    field_state = TodoState.from_name_lazy(other_field)
+                except ValueError:
+                    return _make_error(
+                        protocol, "Parsing", "Invalid field",
+                        "The todo in line {} has the field '{}', but "
+                        "this does neither match a date (\"%d.%m.%Y\") "
+                        "nor a state.".format(
+                            todo_tag.linenumber, other_field))
+        raw_todos.append(
+            (who, what, field_id, field_state, field_date, todo_tag))
     for (_, _, field_id, _, _, _) in raw_todos:
         if field_id is not None:
-            old_todos = [todo for todo in old_todos
-                if todo.id != field_id]
+            old_todos = [
+                todo for todo in old_todos
+                if todo.id != field_id
+            ]
     for todo in old_todos:
         protocol.todos.remove(todo)
     db.session.commit()
@@ -294,28 +329,23 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
         if field_state is None:
             field_state = TodoState.open
         if field_state.needs_date() and field_date is None:
-            error = protocol.create_error("Parsing",
-                "Todo missing date",
+            return _make_error(
+                protocol, "Parsing", "Todo missing date",
                 "The todo in line {} has a state that needs a date, "
                 "but the todo does not have one.".format(todo_tag.linenumber))
-            db.session.add(error)
-            db.session.commit()
-            return
         who = who.strip()
         what = what.strip()
         todo = None
         if field_id is not None:
             todo = Todo.query.filter_by(number=field_id).first()
             if todo is None and not config.PARSER_LAZY:
-                error = protocol.create_error("Parsing",
-                "Invalid Todo ID",
-                "The todo in line {} has the ID {}, but there is no "
-                "Todo with that ID.".format(todo_tag.linenumber, field_id))
-                db.session.add(error)
-                db.session.commit()
-                return
+                return _make_error(
+                    protocol, "Parsing", "Invalid Todo ID",
+                    "The todo in line {} has the ID {}, but there is no "
+                    "Todo with that ID.".format(todo_tag.linenumber, field_id))
         if todo is None and field_id is None and what in old_todo_number_map:
-            todo = Todo(protocoltype_id=protocol.protocoltype.id,
+            todo = Todo(
+                protocoltype_id=protocol.protocoltype.id,
                 who=who, description=what, state=field_state,
                 date=field_date, number=old_todo_number_map[what])
             db.session.add(todo)
@@ -326,7 +356,8 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
                 OldTodo.protocol_key == protocol_key).all()
             if len(old_candidates) == 0:
                 # new protocol
-                todo = Todo(protocoltype_id=protocol.protocoltype.id,
+                todo = Todo(
+                    protocoltype_id=protocol.protocoltype.id,
                     who=who, description=what, state=field_state,
                     date=field_date)
                 db.session.add(todo)
@@ -338,7 +369,8 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
                 number = field_id or lookup_todo_id(old_candidates, who, what)
                 todo = Todo.query.filter_by(number=number).first()
                 if todo is None:
-                    todo = Todo(protocoltype_id=protocol.protocoltype.id,
+                    todo = Todo(
+                        protocoltype_id=protocol.protocoltype.id,
                         who=who, description=what, state=field_state,
                         date=field_date, number=number)
                     db.session.add(todo)
@@ -360,13 +392,12 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
     decision_tags = [tag for tag in tags if tag.name == "beschluss"]
     for decision_tag in decision_tags:
         if decision_tag not in public_elements:
-            error = protocol.create_error("Parsing", "Decision in private context.",
-                "The decision in line {} is in a private context, but decisions are "
-                "and have to be public. Please move it to a public spot.".format(
-                decision_tag.linenumber))
-            db.session.add(error)
-            db.session.commit()
-            return
+            return _make_error(
+                protocol, "Parsing", "Decision in private context.",
+                "The decision in line {} is in a private context, but "
+                "decisions are and have to be public. "
+                "Please move it to a public spot.".format(
+                    decision_tag.linenumber))
     old_decisions = list(protocol.decisions)
     for decision in old_decisions:
         protocol.decisions.remove(decision)
@@ -374,36 +405,35 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
     decisions_to_render = []
     for decision_tag in decision_tags:
         if len(decision_tag.values) == 0:
-            error = protocol.create_error("Parsing", "Empty decision found.",
-                "The decision in line {} is empty.".format(decision_tag.linenumber))
-            db.session.add(error)
-            db.session.commit()
-            return
+            return _make_error(
+                protocol, "Parsing", "Empty decision found.",
+                "The decision in line {} is empty.".format(
+                    decision_tag.linenumber))
         decision_content = decision_tag.values[0]
         decision_categories = []
         for decision_category_name in decision_tag.values[1:]:
-            decision_category = DecisionCategory.query.filter_by(protocoltype_id=protocol.protocoltype.id, name=decision_category_name).first()
+            decision_category = DecisionCategory.query.filter_by(
+                protocoltype_id=protocol.protocoltype.id,
+                name=decision_category_name).first()
             if decision_category is None:
-                category_candidates = DecisionCategory.query.filter_by(protocoltype_id=protocol.protocoltype.id).all()
+                category_candidates = DecisionCategory.query.filter_by(
+                    protocoltype_id=protocol.protocoltype.id).all()
                 category_names = [
                     "'{}'".format(category.name)
                     for category in category_candidates
                 ]
-                error = protocol.create_error("Parsing",
-                    "Unknown decision category",
+                return _make_error(
+                    protocol, "Parsing", "Unknown decision category",
                     "The decision in line {} has the category {}, "
                     "but there is no such category. "
                     "Known categories are {}".format(
                         decision_tag.linenumber,
                         decision_category_name,
                         ", ".join(category_names)))
-                db.session.add(error)
-                db.session.commit()
-                return
             else:
                 decision_categories.append(decision_category)
-        decision = Decision(protocol_id=protocol.id,
-            content=decision_content)
+        decision = Decision(
+            protocol_id=protocol.id, content=decision_content)
         db.session.add(decision)
         db.session.commit()
         for decision_category in decision_categories:
@@ -412,66 +442,67 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
         decisions_to_render.append((decision, decision_tag))
     for decision, decision_tag in decisions_to_render:
         decision_top = decision_tag.fork.get_top()
-        decision_content = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "decision")).render(
-            render_type=RenderType.latex, decision=decision,
-            protocol=protocol, top=decision_top, show_private=True)
+        decision_content = texenv.get_template(provide_latex_template(
+            protocol.protocoltype.latex_template, "decision")).render(
+                render_type=RenderType.latex, decision=decision,
+                protocol=protocol, top=decision_top, show_private=True)
         maxdepth = decision_top.get_maxdepth()
         compile_decision(decision_content, decision, maxdepth=maxdepth)
 
     # Footnotes
-    footnote_tags = [tag for tag in tags if tag.name == "footnote"]
-    public_footnote_tags = [tag for tag in footnote_tags if tag in public_elements]
+    footnote_tags = [
+        tag for tag in tags
+        if tag.name == "footnote"
+    ]
+    public_footnote_tags = [
+        tag for tag in footnote_tags
+        if tag in public_elements
+    ]
 
     # new Protocols
     protocol_tags = [tag for tag in tags if tag.name == "sitzung"]
     for protocol_tag in protocol_tags:
         if len(protocol_tag.values) not in {1, 2}:
-            error = protocol.create_error("Parsing",
-                "Falsche Verwendung von [sitzung;…].",
+            return _make_error(
+                protocol, "Parsing", "Falsche Verwendung von [sitzung;…].",
                 "Der Tag \"sitzung\" benötigt immer ein Datum "
                 "und optional eine Uhrzeit, also ein bis zwei Argumente. "
                 "Stattdessen wurden {} übergeben, nämlich {}".format(
-                len(protocol_tag.values),
-                protocol_tag.values))
-            db.session.add(error)
-            db.ession.commit()
-            return
+                    len(protocol_tag.values),
+                    protocol_tag.values))
         else:
             try:
-                protocol_date = parse_datetime_from_string(
-                    protocol_tag.values[0])
+                parse_datetime_from_string(protocol_tag.values[0])
             except ValueError as exc:
-                error = protocol.create_error("Parsing", "Invalides Datum",
+                return _make_error(
+                    protocol, "Parsing", "Invalides Datum",
                     "'{}' ist kein valides Datum.".format(
                         protocol_tag.values[0]))
-                db.session.add(error)
-                db.session.commit()
-                return
             if len(protocol_tag.values) > 1:
                 try:
-                    protocol_time = datetime.strptime(protocol_tag.values[1], "%H:%M")
+                    datetime.strptime(protocol_tag.values[1], "%H:%M")
                 except ValueError:
-                    error = protocol.create_error("Parsing", "Invalide Uhrzeit",
+                    return _make_error(
+                        protocol, "Parsing", "Invalide Uhrzeit",
                         "'{}' ist keine valide Uhrzeit.".format(
                             protocol_tag.values[1]))
-                    db.session.add(error)
-                    db.session.commit()
-                    return
     for protocol_tag in protocol_tags:
         new_protocol_date = parse_datetime_from_string(protocol_tag.values[0])
         new_protocol_time = None
         if len(protocol_tag.values) > 1:
-            new_protocol_time = datetime.strptime(protocol_tag.values[1], "%H:%M")
-        Protocol.create_new_protocol(protocol.protocoltype,
-            new_protocol_date, new_protocol_time)
+            new_protocol_time = datetime.strptime(
+                protocol_tag.values[1], "%H:%M")
+        Protocol.create_new_protocol(
+            protocol.protocoltype, new_protocol_date, new_protocol_time)
 
     # TOPs
     old_tops = list(protocol.tops)
     for top in old_tops:
         protocol.tops.remove(top)
-    tops = []
-    for index, fork in enumerate((child for child in tree.children if isinstance(child, Fork))):
-        top = TOP(protocol_id=protocol.id, name=fork.name, number=index,
+    for index, fork in enumerate(
+            (child for child in tree.children if isinstance(child, Fork))):
+        top = TOP(
+            protocol_id=protocol.id, name=fork.name, number=index,
             planned=False)
         db.session.add(top)
     db.session.commit()
@@ -485,26 +516,35 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
     public_render_kwargs = copy(private_render_kwargs)
     public_render_kwargs["footnotes"] = public_footnote_tags
     render_kwargs = {True: private_render_kwargs, False: public_render_kwargs}
-    
+
     maxdepth = tree.get_maxdepth()
     privacy_states = [False]
-    content_private = render_template("protocol.txt", render_type=RenderType.plaintext, show_private=True, **private_render_kwargs)
-    content_public = render_template("protocol.txt", render_type=RenderType.plaintext, show_private=False, **public_render_kwargs)
+    content_private = render_template(
+        "protocol.txt", render_type=RenderType.plaintext, show_private=True,
+        **private_render_kwargs)
+    content_public = render_template(
+        "protocol.txt", render_type=RenderType.plaintext, show_private=False,
+        **public_render_kwargs)
     if content_private != content_public:
         privacy_states.append(True)
     protocol.content_private = content_private
     protocol.content_public = content_public
-    protocol.content_html_private = render_template("protocol.html",
-        render_type=RenderType.html, show_private=True, **private_render_kwargs)
-    protocol.content_html_public = render_template("protocol.html",
-        render_type=RenderType.html, show_private=False, **public_render_kwargs)
+    protocol.content_html_private = render_template(
+        "protocol.html", render_type=RenderType.html, show_private=True,
+        **private_render_kwargs)
+    protocol.content_html_public = render_template(
+        "protocol.html", render_type=RenderType.html, show_private=False,
+        **public_render_kwargs)
 
     for show_private in privacy_states:
-        latex_source = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "protocol")).render(
-            render_type=RenderType.latex,
-            show_private=show_private,
-            **render_kwargs[show_private])
-        compile(latex_source, protocol, show_private=show_private, maxdepth=maxdepth)
+        latex_source = texenv.get_template(provide_latex_template(
+            protocol.protocoltype.latex_template, "protocol")).render(
+                render_type=RenderType.latex,
+                show_private=show_private,
+                **render_kwargs[show_private])
+        compile(
+            latex_source, protocol, show_private=show_private,
+            maxdepth=maxdepth)
 
     if protocol.protocoltype.use_wiki:
         wiki_type = WikiType[getattr(config, "WIKI_TYPE", "MEDIAWIKI")]
@@ -525,17 +565,21 @@ def parse_protocol_async_inner(protocol, encoded_kwargs):
         if wiki_type == WikiType.MEDIAWIKI:
             wiki_infobox_source = wikienv.get_template("infobox.wiki").render(
                 protocoltype=protocol.protocoltype)
-            push_to_wiki(protocol, wiki_source, wiki_infobox_source,
+            push_to_wiki(
+                protocol, wiki_source, wiki_infobox_source,
                 "Automatisch generiert vom Protokollsystem 3.0")
         elif wiki_type == WikiType.DOKUWIKI:
-            push_to_dokuwiki(protocol, wiki_source,
+            push_to_dokuwiki(
+                protocol, wiki_source,
                 "Automatisch generiert vom Protokollsystem 3.0")
     protocol.done = True
     db.session.commit()
 
+
 def push_to_wiki(protocol, content, infobox_content, summary):
     push_to_wiki_async.delay(protocol.id, content, infobox_content, summary)
 
+
 @celery.task
 def push_to_wiki_async(protocol_id, content, infobox_content, summary):
     with WikiClient() as wiki_client, app.app_context():
@@ -550,40 +594,48 @@ def push_to_wiki_async(protocol_id, content, infobox_content, summary):
                 content=content,
                 summary=summary)
         except WikiException as exc:
-            error = protocol.create_error("Pushing to Wiki", "Pushing to Wiki failed.", str(exc))
-            db.session.add(error)
-            db.session.commit()
+            return _make_error(
+                protocol, "Pushing to Wiki", "Pushing to Wiki failed.",
+                str(exc))
+
 
 def push_to_dokuwiki(protocol, content, summary):
     push_to_dokuwiki_async.delay(protocol.id, content, summary)
 
+
 @celery.task
 def push_to_dokuwiki_async(protocol_id, content, summary):
     with app.app_context():
         protocol = Protocol.query.filter_by(id=protocol_id).first()
         with xmlrpc.client.ServerProxy(config.WIKI_API_URL) as proxy:
             try:
-                if not proxy.wiki.putPage(protocol.get_wiki_title(),
-                    content, {"sum": "Automatisch generiert vom Protokollsystem 3."}):
-                    error = protocol.create_error("Pushing to Wiki",
+                if not proxy.wiki.putPage(
+                    protocol.get_wiki_title(), content,
+                    {"sum":
+                        "Automatisch generiert vom Protokollsystem 3."}):
+                    return _make_error(
+                        protocol, "Pushing to Wiki",
                         "Pushing to Wiki failed." "")
-                    db.session.add(error)
-                    db.session.commit()
             except xmlrpc.client.Error as exception:
-                error = protocol.create_error("Pushing to Wiki",
-                    "XML RPC Exception",
+                return _make_error(
+                    protocol, "Pushing to Wiki", "XML RPC Exception",
                     str(exception))
-                db.session.add(error)
-                db.session.commit()
+
 
 def compile(content, protocol, show_private, maxdepth):
-   compile_async.delay(content, protocol.id, show_private=show_private, maxdepth=maxdepth)
+    compile_async.delay(
+        content, protocol.id, show_private=show_private, maxdepth=maxdepth)
+
 
 def compile_decision(content, decision, maxdepth):
-    compile_async.delay(content, decision.id, use_decision=True, maxdepth=maxdepth)
+    compile_async.delay(
+        content, decision.id, use_decision=True, maxdepth=maxdepth)
+
 
 @celery.task
-def compile_async(content, protocol_id, show_private=False, use_decision=False, maxdepth=5):
+def compile_async(
+        content, protocol_id, show_private=False, use_decision=False,
+        maxdepth=5):
     with tempfile.TemporaryDirectory() as compile_dir, app.app_context():
         decision = None
         protocol = None
@@ -598,10 +650,19 @@ def compile_async(content, protocol_id, show_private=False, use_decision=False,
             protocol_target_filename = "protocol.pdf"
             protocol_class_filename = "protokoll2.cls"
             log_filename = "protocol.log"
-            with open(os.path.join(compile_dir, protocol_source_filename), "w") as source_file:
+            with open(
+                    os.path.join(compile_dir, protocol_source_filename),
+                    "w") as source_file:
                 source_file.write(content)
-            protocol2_class_source = texenv.get_template(provide_latex_template(protocol.protocoltype.latex_template, "class")).render(fonts=config.FONTS, maxdepth=maxdepth, bulletpoints=config.LATEX_BULLETPOINTS)
-            with open(os.path.join(compile_dir, protocol_class_filename), "w") as protocol2_class_file:
+            protocol2_class_source = texenv.get_template(
+                provide_latex_template(
+                    protocol.protocoltype.latex_template,
+                    "class")).render(
+                fonts=config.FONTS, maxdepth=maxdepth,
+                bulletpoints=config.LATEX_BULLETPOINTS)
+            with open(
+                os.path.join(compile_dir, protocol_class_filename),
+                    "w") as protocol2_class_file:
                 protocol2_class_file.write(protocol2_class_source)
             os.chdir(compile_dir)
             command = [
@@ -610,15 +671,23 @@ def compile_async(content, protocol_id, show_private=False, use_decision=False,
                 "-file-line-error",
                 protocol_source_filename
             ]
-            subprocess.check_call(command, universal_newlines=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
-            subprocess.check_call(command, universal_newlines=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+            subprocess.check_call(
+                command, universal_newlines=True, stdout=subprocess.DEVNULL,
+                stderr=subprocess.DEVNULL)
+            subprocess.check_call(
+                command, universal_newlines=True, stdout=subprocess.DEVNULL,
+                stderr=subprocess.DEVNULL)
             os.chdir(current)
             document = None
             if not use_decision:
-                for old_document in [document for document in protocol.documents if document.is_compiled and document.is_private == show_private]:
+                for old_document in [
+                    document for document in protocol.documents
+                    if document.is_compiled
+                        and document.is_private == show_private]:
                     protocol.documents.remove(old_document)
                 db.session.commit()
-                document = Document(protocol_id=protocol.id,
+                document = Document(
+                    protocol_id=protocol.id,
                     name="protokoll{}_{}_{}.pdf".format(
                         "_intern" if show_private else "",
                         protocol.protocoltype.short_name,
@@ -627,7 +696,8 @@ def compile_async(content, protocol_id, show_private=False, use_decision=False,
                     is_compiled=True,
                     is_private=show_private)
             else:
-                document = DecisionDocument(decision_id=decision.id,
+                document = DecisionDocument(
+                    decision_id=decision.id,
                     name="beschluss_{}_{}_{}.pdf".format(
                         protocol.protocoltype.short_name,
                         date_filter_short(protocol.date),
@@ -635,48 +705,60 @@ def compile_async(content, protocol_id, show_private=False, use_decision=False,
                     filename="")
             db.session.add(document)
             db.session.commit()
-            target_filename = "compiled-{}-{}.pdf".format(document.id, "internal" if show_private else "public")
+            target_filename = "compiled-{}-{}.pdf".format(
+                document.id, "internal" if show_private else "public")
             if use_decision:
-                target_filename = "decision-{}-{}-{}.pdf".format(protocol.id, decision.id, document.id)
+                target_filename = "decision-{}-{}-{}.pdf".format(
+                    protocol.id, decision.id, document.id)
             document.filename = target_filename
-            shutil.copy(os.path.join(compile_dir, protocol_target_filename), os.path.join(config.DOCUMENTS_PATH, target_filename))
+            shutil.copy(
+                os.path.join(compile_dir, protocol_target_filename),
+                os.path.join(config.DOCUMENTS_PATH, target_filename))
             db.session.commit()
-            shutil.copy(os.path.join(compile_dir, log_filename), "/tmp/proto-tex.log")
+            shutil.copy(
+                os.path.join(compile_dir, log_filename),
+                "/tmp/proto-tex.log")
         except subprocess.SubprocessError:
             log = ""
             total_log_filename = os.path.join(compile_dir, log_filename)
-            total_source_filename = os.path.join(compile_dir, protocol_source_filename)
+            total_source_filename = os.path.join(
+                compile_dir, protocol_source_filename)
             log = ""
             if os.path.isfile(total_source_filename):
                 with open(total_source_filename, "r") as source_file:
                     log += "Source:\n\n" + add_line_numbers(source_file.read())
-            total_class_filename = os.path.join(compile_dir, protocol_class_filename)
+            total_class_filename = os.path.join(
+                compile_dir, protocol_class_filename)
             if os.path.isfile(total_class_filename):
                 with open(total_class_filename, "r") as class_file:
-                    log += "\n\nClass:\n\n" + add_line_numbers(class_file.read())
+                    log += "\n\nClass:\n\n" + add_line_numbers(
+                        class_file.read())
             if os.path.isfile(total_log_filename):
                 with open(total_log_filename, "r") as log_file:
                     log += "\n\nLog:\n\n" + add_line_numbers(log_file.read())
             else:
                 log += "\n\nLogfile not found."
-            error = protocol.create_error("Compiling", "Compiling LaTeX failed", log)
-            db.session.add(error)
-            db.session.commit()
+            _make_error(protocol, "Compiling", "Compiling LaTeX failed", log)
         finally:
             os.chdir(current)
 
+
 def print_file(filename, protocol):
     if config.PRINTING_ACTIVE:
         print_file_async.delay(filename, protocol.id)
 
+
 @celery.task
 def print_file_async(filename, protocol_id):
     with app.app_context():
         protocol = Protocol.query.filter_by(id=protocol_id).first()
         if protocol.protocoltype.printer is None:
-            error = protocol.create_error("Printing", "No printer configured.", "You don't have any printer configured for the protocoltype {}. Please do so before printing a protocol.".format(protocol.protocoltype.name))
-            db.session.add(error)
-            db.session.commit()
+            return _make_error(
+                protocol, "Printing", "No printer configured.",
+                "You don't have any printer configured for the "
+                "protocoltype {}. "
+                "Please do so before printing a protocol.".format(
+                    protocol.protocoltype.name))
         try:
             command = [
                 "/usr/bin/lpr",
@@ -685,70 +767,96 @@ def print_file_async(filename, protocol_id):
                 "-U", config.PRINTING_USER,
                 "-T", protocol.get_identifier(),
             ]
-            for option in config.PRINTING_PRINTERS[protocol.protocoltype.printer]:
-                command.extend(["-o", '"{}"'.format(option) if " " in option else option])
+            for option in config.PRINTING_PRINTERS[
+                    protocol.protocoltype.printer]:
+                command.extend([
+                    "-o", '"{}"'.format(option)
+                    if " " in option else option])
             command.append(filename)
-            subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT)
+            subprocess.check_output(
+                command, universal_newlines=True, stderr=subprocess.STDOUT)
         except subprocess.SubprocessError as exception:
-            error = protocol.create_error("Printing", "Printing {} failed.".format(protocol.get_identifier()), exception.stdout)
-            db.session.add(error)
-            db.session.commit()
+            return _make_error(
+                protocol, "Printing", "Printing {} failed.".format(
+                    protocol.get_identifier()), exception.stdout)
+
 
 def send_reminder(reminder, protocol):
     send_reminder_async.delay(reminder.id, protocol.id)
 
+
 @celery.task
 def send_reminder_async(reminder_id, protocol_id):
     with app.app_context():
         reminder = MeetingReminder.query.filter_by(id=reminder_id).first()
         protocol = Protocol.query.filter_by(id=protocol_id).first()
-        reminder_text = render_template("reminder-mail.txt", reminder=reminder, protocol=protocol)
+        reminder_text = render_template(
+            "reminder-mail.txt", reminder=reminder, protocol=protocol)
         if reminder.send_public:
-            print("sending public reminder mail to {}".format(protocol.protocoltype.public_mail))
-            send_mail(protocol, protocol.protocoltype.public_mail,
+            send_mail(
+                protocol, protocol.protocoltype.public_mail,
                 "Tagesordnung der {}".format(protocol.protocoltype.name),
                 reminder_text, reply_to=protocol.protocoltype.public_mail)
         if reminder.send_private:
-            print("sending private reminder mail to {}".format(protocol.protocoltype.private_mail))
-            send_mail(protocol, protocol.protocoltype.private_mail,
+            send_mail(
+                protocol, protocol.protocoltype.private_mail,
                 "Tagesordnung der {}".format(protocol.protocoltype.name),
                 reminder_text, reply_to=protocol.protocoltype.private_mail)
 
+
 def remind_finishing(protocol, delay_days, min_delay_days):
     remind_finishing_async.delay(protocol.id, delay_days, min_delay_days)
 
+
 @celery.task
 def remind_finishing_async(protocol_id, delay_days, min_delay_days):
     with app.app_context():
-        protocol = Protocol.query.filter_by(id=protocol_id).first()
-        mail_text = render_template("remind-finishing-mail.txt",
+        protocol = Protocol.first_by_id(protocol_id)
+        mail_text = render_template(
+            "remind-finishing-mail.txt",
             protocol=protocol, delay_days=delay_days,
             min_delay_days=min_delay_days)
-        send_mail(protocol, protocol.protocoltype.private_mail,
+        send_mail(
+            protocol, protocol.protocoltype.private_mail,
             "Unfertiges Protokoll der {}".format(protocol.protocoltype.name),
             mail_text, reply_to=protocol.protocoltype.private_mail)
 
+
 def send_protocol_private(protocol):
     send_protocol_async.delay(protocol.id, show_private=True)
     send_todomails_async.delay(protocol.id)
 
+
 def send_protocol_public(protocol):
     send_protocol_async.delay(protocol.id, show_private=False)
 
+
 @celery.task
 def send_protocol_async(protocol_id, show_private):
     with app.app_context():
         protocol = Protocol.query.filter_by(id=protocol_id).first()
-        next_protocol = Protocol.query.filter_by(protocoltype_id=protocol.protocoltype.id).filter_by(done=False).filter(Protocol.date > datetime.now()).order_by(Protocol.date).first()
-        to_addr = protocol.protocoltype.private_mail if show_private else protocol.protocoltype.public_mail
-        subject = "{}{}-Protokoll vom {}".format("Internes " if show_private else "", protocol.protocoltype.short_name, date_filter(protocol.date))
-        mail_content = render_template("protocol-mail.txt", protocol=protocol, show_private=show_private, next_protocol=next_protocol)
-        appendix = [(document.name, document.as_file_like())
+        next_protocol = Protocol.query.filter_by(
+            protocoltype_id=protocol.protocoltype.id).filter_by(
+            done=False).filter(
+            Protocol.date > datetime.now()).order_by(Protocol.date).first()
+        to_addr = (
+            protocol.protocoltype.private_mail
+            if show_private
+            else protocol.protocoltype.public_mail)
+        subject = "{}{}-Protokoll vom {}".format(
+            "Internes " if show_private else "",
+            protocol.protocoltype.short_name, date_filter(protocol.date))
+        mail_content = render_template(
+            "protocol-mail.txt", protocol=protocol, show_private=show_private,
+            next_protocol=next_protocol)
+        appendix = [
+            (document.name, document.as_file_like())
             for document in protocol.documents
             if show_private or not document.is_private
         ]
         send_mail(protocol, to_addr, subject, mail_content, appendix)
 
+
 @celery.task
 def send_todomails_async(protocol_id):
     with app.app_context():
@@ -764,7 +872,8 @@ def send_todomails_async(protocol_id):
             for user in users
         }
         subject = "Du hast noch was zu tun!"
-        todomail_providers = getattr(config, "ADDITIONAL_TODOMAIL_PROVIDERS", None)
+        todomail_providers = getattr(
+            config, "ADDITIONAL_TODOMAIL_PROVIDERS", None)
         additional_todomails = {}
         if todomail_providers:
             for provider in todomail_providers:
@@ -779,33 +888,42 @@ def send_todomails_async(protocol_id):
                 if user in additional_todomails:
                     todomail = additional_todomails[user]
             if todomail is None:
-                error = protocol.create_error("Sending Todomail", "Sending Todomail failed.", "User {} has no Todo-Mail-Assignment.".format(user))
-                db.session.add(error)
-                db.session.commit()
+                _make_error(
+                    protocol, "Sending Todomail", "Sending Todomail failed.",
+                    "User {} has no Todo-Mail-Assignment.".format(user))
                 continue
             to_addr = todomail.get_formatted_mail()
-            mail_content = render_template("todo-mail.txt", protocol=protocol, todomail=todomail, todos=grouped_todos[user])
-            send_mail(protocol, to_addr, subject, mail_content,
+            mail_content = render_template(
+                "todo-mail.txt", protocol=protocol, todomail=todomail,
+                todos=grouped_todos[user])
+            send_mail(
+                protocol, to_addr, subject, mail_content,
                 reply_to=protocol.protocoltype.private_mail)
 
-def send_mail(protocol, to_addr, subject, content, appendix=None, reply_to=None):
+
+def send_mail(protocol, to_addr, subject, content, appendix=None,
+              reply_to=None):
     if to_addr is not None and len(to_addr.strip()) > 0:
-        send_mail_async.delay(protocol.id, to_addr, subject, content, appendix, reply_to)
+        send_mail_async.delay(
+            protocol.id, to_addr, subject, content, appendix, reply_to)
+
 
 @celery.task
-def send_mail_async(protocol_id, to_addr, subject, content, appendix, reply_to):
+def send_mail_async(protocol_id, to_addr, subject, content, appendix,
+                    reply_to):
     with app.app_context():
         protocol = Protocol.query.filter_by(id=protocol_id).first()
         try:
             mail_manager.send(to_addr, subject, content, appendix, reply_to)
         except Exception as exc:
-            error = protocol.create_error("Sending Mail", "Sending mail failed", str(exc))
-            db.session.add(error)
-            db.session.commit()
+            return _make_error(
+                protocol, "Sending Mail", "Sending mail failed", str(exc))
+
 
 def push_tops_to_calendar(protocol):
     push_tops_to_calendar_async.delay(protocol.id)
 
+
 @celery.task
 def push_tops_to_calendar_async(protocol_id):
     if not config.CALENDAR_ACTIVE:
@@ -817,21 +935,22 @@ def push_tops_to_calendar_async(protocol_id):
         description = render_template("calendar-tops.txt", protocol=protocol)
         try:
             client = CalendarClient(protocol.protocoltype.calendar)
-            client.set_event_at(begin=protocol.get_datetime(),
+            client.set_event_at(
+                begin=protocol.get_datetime(),
                 name=protocol.protocoltype.short_name, description=description)
         except CalendarException as exc:
-            error = protocol.create_error("Calendar",
+            return _make_error(
+                protocol, "Calendar",
                 "Pushing TOPs to Calendar failed", str(exc))
-            db.session.add(error)
-            db.session.commit()
+
 
 def set_etherpad_content(protocol):
     set_etherpad_content_async.delay(protocol.id)
 
+
 @celery.task
 def set_etherpad_content_async(protocol_id):
     with app.app_context():
         protocol = Protocol.query.filter_by(id=protocol_id).first()
         identifier = protocol.get_identifier()
         return set_etherpad_text(identifier, protocol.get_template())
-