Files
kandev/apps/backend/internal/task/handlers/errors.go
T
José Almeida c64e835612 feat: allow moving tasks across workflows (#822)
* feat: allow moving tasks across workflows

* fix: address PR review feedback

* fix: address remaining PR review feedback

* fix: remove unreachable move state event

* fix: map task move conflicts correctly

* fix: address PR review nitpicks

* fix: use neutral task move error message
2026-05-05 14:13:43 +01:00

67 lines
1.8 KiB
Go

package handlers
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/kandev/kandev/internal/common/logger"
"go.uber.org/zap"
)
func handleNotFound(c *gin.Context, log *logger.Logger, err error, fallback string) {
if isNotFound(err) {
c.JSON(http.StatusNotFound, gin.H{"error": fallback})
return
}
if isValidationError(err) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
log.Error("request failed", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": "request failed"})
}
func handleSelectedMoveError(c *gin.Context, log *logger.Logger, err error) {
switch {
case isNotFound(err):
c.JSON(http.StatusNotFound, gin.H{"error": "task or workflow not found"})
case isMoveConflict(err):
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
case isValidationError(err):
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
default:
log.Error("task move failed", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": "task move failed"})
}
}
func isNotFound(err error) bool {
if err == nil {
return false
}
return strings.Contains(strings.ToLower(err.Error()), "not found")
}
func isMoveConflict(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "active session") ||
strings.Contains(msg, "archived tasks cannot be moved") ||
strings.Contains(msg, "different workspace") ||
strings.Contains(msg, "does not belong to target workflow")
}
func isValidationError(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "pending approval") ||
strings.Contains(msg, "validation") ||
strings.Contains(msg, "required") ||
strings.Contains(msg, "invalid")
}