FIX[BE]: fix error handling on chickin service to better handler

This commit is contained in:
aguhh18
2025-11-04 16:34:36 +07:00
parent 8220e34302
commit 48730e1b74
@@ -152,7 +152,7 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
for _, productWarehouse := range productWarehouses {
availableQty, err := s.calculateAvailableQuantity(c, req.ProjectFlockKandangId, &productWarehouse, category)
if err != nil {
s.Log.Warnf("Failed to calculate available quantity for product warehouse %d: %v", productWarehouse.Id, err)
return nil, fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to calculate available quantity for product warehouse %d", productWarehouse.Id))
}
if availableQty <= 0 {
@@ -189,12 +189,12 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
if err := s.Repository.WithTx(dbTransaction).CreateMany(c.Context(), newChikins, nil); err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
}
latest, err := approvalSvcTx.LatestByTarget(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, nil)
if err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get latest approval")
}
if category == string(utils.ProjectFlockCategoryLaying) {
@@ -218,17 +218,29 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
}
if latest == nil {
if _, err := approvalSvcTx.CreateApproval(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, utils.ProjectFlockKandangStepPengajuan, &approvalAction, actorID, nil); err != nil {
lower := strings.ToLower(err.Error())
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
return err
if _, err := approvalSvcTx.CreateApproval(
c.Context(),
utils.ApprovalWorkflowProjectFlockKandang,
projectFlockKandang.Id,
utils.ProjectFlockKandangStepPengajuan,
&approvalAction,
actorID,
nil); err != nil {
if !errors.Is(err, gorm.ErrDuplicatedKey) {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
}
}
} else if latest.StepNumber != uint16(utils.ProjectFlockKandangStepPengajuan) {
if _, err := approvalSvcTx.CreateApproval(c.Context(), utils.ApprovalWorkflowProjectFlockKandang, projectFlockKandang.Id, utils.ProjectFlockKandangStepPengajuan, &approvalAction, actorID, nil); err != nil {
lower := strings.ToLower(err.Error())
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
return err
if _, err := approvalSvcTx.CreateApproval(
c.Context(),
utils.ApprovalWorkflowProjectFlockKandang,
projectFlockKandang.Id,
utils.ProjectFlockKandangStepPengajuan,
&approvalAction,
actorID,
nil); err != nil {
if !errors.Is(err, gorm.ErrDuplicatedKey) {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
}
}
}
@@ -236,7 +248,10 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
return nil
})
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, err.Error())
if fiberErr, ok := err.(*fiber.Error); ok {
return nil, fiberErr
}
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create chickins")
}
result := make([]entity.ProjectChickin, 0, len(newChikins))
@@ -324,7 +339,6 @@ func (s chickinService) calculateAvailableQuantity(ctx *fiber.Ctx, projectFlockK
totalPopulation += pop.TotalQty
}
}
chickins, err := s.Repository.GetByProjectFlockKandangID(ctx.Context(), projectFlockKandangID)
if err == nil {
for _, chickin := range chickins {
@@ -334,7 +348,6 @@ func (s chickinService) calculateAvailableQuantity(ctx *fiber.Ctx, projectFlockK
}
}
}
availableQty = productWarehouse.Quantity - totalPopulation - totalPendingQty
if availableQty < 0 {
availableQty = 0
@@ -397,7 +410,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
productWarehouseTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
for _, approvableID := range approvableIDs {
actorID := uint(1) // todo nanti ambil dari auth context
if _, err := approvalSvc.CreateApproval(
c.Context(),
@@ -408,19 +420,13 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
actorID,
req.Notes,
); err != nil {
lower := strings.ToLower(err.Error())
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
return err
}
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create approval")
}
if action == entity.ApprovalActionApproved {
chickins, err := chickinRepoTx.GetByProjectFlockKandangID(c.Context(), approvableID)
if err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to get chickins for approval %d", approvableID))
}
kandangForApproval, err := s.ProjectflockKandangRepo.GetByID(c.Context(), approvableID)
@@ -428,7 +434,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
}
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get ProjectFlockKandang")
}
category := strings.ToUpper(strings.TrimSpace(kandangForApproval.ProjectFlock.Category))
@@ -439,41 +445,38 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
}
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get warehouse")
}
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
if err != nil {
return fmt.Errorf("failed to get/create PULLET product warehouse: %w", err)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get/create PULLET product warehouse")
}
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to convert chickins to target")
}
} else if category == string(utils.ProjectFlockCategoryLaying) {
warehouse, err := s.WarehouseRepo.GetByKandangID(c.Context(), kandangForApproval.KandangId)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Warehouse for kandang %d not found", kandangForApproval.KandangId))
}
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get warehouse")
}
targetPW, err := s.getOrCreateProductWarehouse(c, warehouse.Id, "PULLET", dbTransaction, actorID)
if err != nil {
return fmt.Errorf("failed to get/create PULLET product warehouse: %w", err)
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get/create PULLET product warehouse")
}
if err := s.convertChickinsToTarget(c, chickins, targetPW, dbTransaction, actorID); err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to convert chickins to target")
}
}
}
if action == entity.ApprovalActionRejected {
chickins, err := chickinRepoTx.GetPendingByProjectFlockKandangID(c.Context(), approvableID)
if err != nil {
return fmt.Errorf("failed to get pending chickins for rejection %d: %w", approvableID, err)
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to get pending chickins for rejection %d", approvableID))
}
if len(chickins) == 0 {
@@ -485,7 +488,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("ProjectFlockKandang %d not found", approvableID))
}
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get ProjectFlockKandang")
}
categoryForRejection := strings.ToUpper(strings.TrimSpace(kandangForRejection.ProjectFlock.Category))
@@ -499,15 +502,14 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Product warehouse %d not found during rejection", chickin.ProductWarehouseId))
}
return fmt.Errorf("failed to restore product warehouse quantity for chickin %d: %w", chickin.Id, err)
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to restore product warehouse quantity for chickin %d", chickin.Id))
}
}
if err := chickinRepoTx.DeleteOne(c.Context(), chickin.Id); err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("failed to delete rejected chickin %d: %w", chickin.Id, err)
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to delete rejected chickin %d", chickin.Id))
}
s.Log.Infof("chickin %d already deleted during rejection", chickin.Id)
}
}
}
@@ -519,9 +521,6 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
if fiberErr, ok := err.(*fiber.Error); ok {
return nil, fiberErr
}
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fiber.NewError(fiber.StatusNotFound, "Chickin not found")
}
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to record approval")
}
@@ -529,7 +528,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
for _, kandangID := range approvableIDs {
var chickins []entity.ProjectChickin
if err := s.Repository.DB().WithContext(c.Context()).Where("project_flock_kandang_id = ?", kandangID).Find(&chickins).Error; err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to load approved chickins")
}
updated = append(updated, chickins...)
}
@@ -608,7 +607,6 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
}
}
// Add to target product warehouse
if err := productWarehouseTx.PatchOne(ctx.Context(), targetPW.Id, map[string]any{
"quantity": gorm.Expr("quantity + ?", quantityToConvert),
}, nil); err != nil {
@@ -627,11 +625,7 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
CreatedBy: actorID,
}
if err := ProjectFlockPopulationRepotx.CreateOne(ctx.Context(), population, nil); err != nil {
lower := strings.ToLower(err.Error())
if !(strings.Contains(lower, "duplicate") || strings.Contains(lower, "unique constraint") || strings.Contains(lower, "23505")) {
return err
}
s.Log.Infof("ignored duplicate population for chickin %d: %v", chickin.Id, err)
return err
}
}