webhooks: add error handling for patch submission

Currently, any 400 error that occurs will be swallowed by
`SrhtService.post()` [1] - the caller must use a validation object to
become aware of an error.

This commit adds such error handling by means of a validation object to
the build submission webhook.

[1]: https://git.sr.ht/~sircmpwn/hub.sr.ht/tree/f37b9e6e/item/hubsrht/services.py#L56-60
This commit is contained in:
Conrad Hoffmann 2022-11-24 14:29:46 +01:00 committed by Drew DeVault
parent f37b9e6e18
commit ec7a552ffc
3 changed files with 13 additions and 8 deletions

View File

@ -13,6 +13,7 @@ from srht.config import get_origin
from srht.crypto import fernet, verify_request_signature
from srht.database import db
from srht.flask import csrf_bypass
from srht.validation import Validation
from urllib.parse import quote
webhooks = Blueprint("webhooks", __name__)
@ -269,7 +270,11 @@ def mailing_list(list_id):
db.session.commit()
return "Thanks!"
elif event == "patchset:received":
build_ids = submit_patchset(ml, payload)
valid = Validation(request)
build_ids = submit_patchset(ml, payload, valid)
if not valid.ok:
emsg = f"{valid.errors[0].field}: {valid.errors[0].message}"
return f"Error submitting builds: {emsg}", 400
if build_ids:
return f"Submitted builds #{build_ids}. Thanks!"
else:

View File

@ -9,7 +9,7 @@ from sqlalchemy import func
from srht.config import get_origin
from srht.crypto import fernet
def submit_patchset(ml, payload):
def submit_patchset(ml, payload, valid=None):
buildsrht = get_origin("builds.sr.ht", external=True, default=None)
if not buildsrht:
return None
@ -107,7 +107,7 @@ git am -3 /tmp/{payload["id"]}.patch"""
}))
b = builds.submit_build(project.owner, manifest, build_note,
tags=[repo.name, "patches", key], execute=False)
tags=[repo.name, "patches", key], execute=False, valid=valid)
ids.append(b["id"])
build_url = f"{buildsrht}/{project.owner.canonical_name}/job/{b['id']}"
lists.patchset_update_tool(ml.owner, tool_id, "WAITING",
@ -120,5 +120,5 @@ git am -3 /tmp/{payload["id"]}.patch"""
trigger.attrs["to"] = email.utils.formataddr(submitter)
trigger.attrs["cc"] = ml.posting_addr()
trigger.attrs["in_reply_to"] = payload["message_id"]
builds.create_group(project.owner, ids, build_note, [trigger.to_dict()])
builds.create_group(project.owner, ids, build_note, [trigger.to_dict()], valid=valid)
return ids

View File

@ -572,8 +572,8 @@ class TodoService(SrhtService):
self.put(user, None, url, payload)
class BuildService(SrhtService):
def submit_build(self, user, manifest, note, tags, execute=True):
return self.post(user, None, f"{_buildsrht}/api/jobs", {
def submit_build(self, user, manifest, note, tags, execute=True, valid=None):
return self.post(user, valid, f"{_buildsrht}/api/jobs", {
"manifest": yaml.dump(manifest.to_dict(), default_flow_style=False),
"tags": tags,
"note": note,
@ -581,8 +581,8 @@ class BuildService(SrhtService):
"execute": execute,
})
def create_group(self, user, job_ids, note, triggers):
return self.post(user, None, f"{_buildsrht}/api/job-group", {
def create_group(self, user, job_ids, note, triggers, valid=None):
return self.post(user, valid, f"{_buildsrht}/api/job-group", {
"jobs": job_ids,
"note": note,
"execute": True,