diff --git a/pkg/http/ticketupload.go b/pkg/http/ticketupload.go index de23a52..3828408 100644 --- a/pkg/http/ticketupload.go +++ b/pkg/http/ticketupload.go @@ -44,6 +44,54 @@ func (s *Server) ticketUploadHandler(ctx *gin.Context) { return } + // Handle failed uploads: delete object from DB and S3 and re-upload + var existingObject *model.Object + if err := s.store.Tx(ctx, func(r repository.Repositories) error { + obj, alreadyExists, err := r.Objects().GetObject(ctx, guild, id) + if err != nil { + return err + } + + if alreadyExists { + existingObject = &obj + } + + return nil + }); err != nil { + s.Logger.Error("Failed to check whether object already exists", zap.Error(err)) + return + } + + // If the object is already found, delete from S3 + if existingObject != nil { + c, err := s.s3Clients.Get(existingObject.BucketId) + if err != nil { + s.Logger.Error("Failed to get client for existing object", zap.Error(err)) + ctx.JSON(500, gin.H{ + "message": err.Error(), + }) + return + } + + if err := c.DeleteTicket(ctx, guild, id); err != nil { + s.Logger.Error("Failed to delete existing ticket", zap.Error(err)) + ctx.JSON(500, gin.H{ + "message": err.Error(), + }) + return + } + + if err := s.store.Tx(ctx, func(r repository.Repositories) error { + return r.Objects().DeleteObject(ctx, guild, id) + }); err != nil { + s.Logger.Error("Failed to delete object from DB", zap.Error(err)) + ctx.JSON(500, gin.H{ + "message": err.Error(), + }) + return + } + } + // Create object and commit transaction BEFORE writing to S3, to prevent "lost" objects if err := s.store.Tx(ctx, func(r repository.Repositories) error { return r.Objects().CreateObject(ctx, model.Object{