feat(caldav): add more error logging

This commit is contained in:
kolaente
2025-12-04 10:54:21 +01:00
parent 30104fb749
commit da0822c3f4
2 changed files with 50 additions and 6 deletions

View File

@@ -265,6 +265,7 @@ func getHexColorFromCaldavColor(caldavColor string) string {
return hexColor
}
//nolint:gocyclo
func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
parsed, err := ics.ParseCalendar(strings.NewReader(content))
if err != nil {
@@ -301,11 +302,23 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
}
}
// Get UID and SUMMARY (log warning if missing, but don't fail for backwards compatibility)
uid, hasUID := task["UID"]
if !hasUID {
log.Warningf("[CALDAV] VTODO missing UID field")
}
summary, hasSummary := task["SUMMARY"]
if !hasSummary {
log.Warningf("[CALDAV] VTODO missing SUMMARY field")
}
// Parse the priority
var priority int64
if _, ok := task["PRIORITY"]; ok {
priorityParsed, err := strconv.ParseInt(task["PRIORITY"].Value, 10, 64)
if err != nil {
log.Errorf("[CALDAV] Failed to parse PRIORITY: %v", err)
return nil, err
}
@@ -313,10 +326,16 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
}
// Parse the enddate
duration, _ := time.ParseDuration(task["DURATION"].Value)
var duration time.Duration
if durationProp, ok := task["DURATION"]; ok {
duration, _ = time.ParseDuration(durationProp.Value)
}
description := strings.ReplaceAll(task["DESCRIPTION"].Value, "\\,", ",")
description = strings.ReplaceAll(description, "\\n", "\n")
description := ""
if descProp, ok := task["DESCRIPTION"]; ok {
description = strings.ReplaceAll(descProp.Value, "\\,", ",")
description = strings.ReplaceAll(description, "\\n", "\n")
}
var labels []*models.Label
if val, ok := task["CATEGORIES"]; ok {
@@ -329,9 +348,18 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
}
}
// Safely extract values
var uidValue, titleValue string
if hasUID {
uidValue = uid.Value
}
if hasSummary {
titleValue = summary.Value
}
vTask = &models.Task{
UID: task["UID"].Value,
Title: task["SUMMARY"].Value,
UID: uidValue,
Title: titleValue,
Description: description,
Priority: priority,
Labels: labels,
@@ -371,7 +399,7 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
})
}
if task["STATUS"].Value == "COMPLETED" {
if status, ok := task["STATUS"]; ok && status.Value == "COMPLETED" {
vTask.Done = true
}

View File

@@ -288,6 +288,8 @@ func (vcls *VikunjaCaldavProjectStorage) CreateResource(rpath, content string) (
vTask, err := caldav.ParseTaskFromVTODO(content)
if err != nil {
log.Errorf("[CALDAV] Failed to parse VTODO in CreateResource: %v", err)
log.Debugf("[CALDAV] VTODO content that failed to parse: %s", content)
return nil, err
}
@@ -296,15 +298,18 @@ func (vcls *VikunjaCaldavProjectStorage) CreateResource(rpath, content string) (
// Check the permissions
canCreate, err := vTask.CanCreate(s, vcls.user)
if err != nil {
log.Errorf("[CALDAV] Permission check failed in CreateResource for user %s, project %d: %v", vcls.user.Username, vcls.project.ID, err)
return nil, err
}
if !canCreate {
log.Warningf("[CALDAV] User %s does not have permission to create task in project %d", vcls.user.Username, vcls.project.ID)
return nil, errs.ForbiddenError
}
// Create the task
err = vTask.Create(s, vcls.user)
if err != nil {
log.Errorf("[CALDAV] Failed to create task in CreateResource: %v, task: %+v", err, vTask)
_ = s.Rollback()
return nil, err
}
@@ -312,6 +317,7 @@ func (vcls *VikunjaCaldavProjectStorage) CreateResource(rpath, content string) (
vcls.task.ID = vTask.ID
err = persistLabels(s, vcls.user, vcls.task, vTask.Labels)
if err != nil {
log.Errorf("[CALDAV] Failed to persist labels in CreateResource: %v, labels: %+v", err, vTask.Labels)
_ = s.Rollback()
return nil, err
}
@@ -319,11 +325,13 @@ func (vcls *VikunjaCaldavProjectStorage) CreateResource(rpath, content string) (
vcls.task.ProjectID = vcls.project.ID
err = persistRelations(s, vcls.user, vcls.task, vTask.RelatedTasks)
if err != nil {
log.Errorf("[CALDAV] Failed to persist relations in CreateResource: %v, relations: %+v", err, vTask.RelatedTasks)
_ = s.Rollback()
return nil, err
}
if err := s.Commit(); err != nil {
log.Errorf("[CALDAV] Failed to commit transaction in CreateResource: %v", err)
return nil, err
}
@@ -341,6 +349,8 @@ func (vcls *VikunjaCaldavProjectStorage) UpdateResource(rpath, content string) (
vTask, err := caldav.ParseTaskFromVTODO(content)
if err != nil {
log.Errorf("[CALDAV] Failed to parse VTODO in UpdateResource: %v", err)
log.Debugf("[CALDAV] VTODO content that failed to parse: %s", content)
return nil, err
}
@@ -357,10 +367,12 @@ func (vcls *VikunjaCaldavProjectStorage) UpdateResource(rpath, content string) (
// Check the permissions
canUpdate, err := vTask.CanUpdate(s, vcls.user)
if err != nil {
log.Errorf("[CALDAV] Permission check failed in UpdateResource for user %s, task %d: %v", vcls.user.Username, vcls.task.ID, err)
_ = s.Rollback()
return nil, err
}
if !canUpdate {
log.Warningf("[CALDAV] User %s does not have permission to update task %d", vcls.user.Username, vcls.task.ID)
_ = s.Rollback()
return nil, errs.ForbiddenError
}
@@ -368,23 +380,27 @@ func (vcls *VikunjaCaldavProjectStorage) UpdateResource(rpath, content string) (
// Update the task
err = vTask.Update(s, vcls.user)
if err != nil {
log.Errorf("[CALDAV] Failed to update task in UpdateResource: %v, task: %+v", err, vTask)
_ = s.Rollback()
return nil, err
}
err = persistLabels(s, vcls.user, vcls.task, vTask.Labels)
if err != nil {
log.Errorf("[CALDAV] Failed to persist labels in UpdateResource: %v, labels: %+v", err, vTask.Labels)
_ = s.Rollback()
return nil, err
}
err = persistRelations(s, vcls.user, vcls.task, vTask.RelatedTasks)
if err != nil {
log.Errorf("[CALDAV] Failed to persist relations in UpdateResource: %v, relations: %+v", err, vTask.RelatedTasks)
_ = s.Rollback()
return nil, err
}
if err := s.Commit(); err != nil {
log.Errorf("[CALDAV] Failed to commit transaction in UpdateResource: %v", err)
return nil, err
}