Skip to content

Commit

Permalink
[api] use 409 instead of 500 on ID conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
capcom6 committed Jul 10, 2024
1 parent 1515eb3 commit f395a96
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 12 deletions.
6 changes: 6 additions & 0 deletions api/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@
"$ref": "#/definitions/smsgateway.ErrorResponse"
}
},
"409": {
"description": "Message with such ID already exists",
"schema": {
"$ref": "#/definitions/smsgateway.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
Expand Down
4 changes: 4 additions & 0 deletions api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ paths:
description: Unauthorized
schema:
$ref: '#/definitions/smsgateway.ErrorResponse'
"409":
description: Message with such ID already exists
schema:
$ref: '#/definitions/smsgateway.ErrorResponse'
"500":
description: Internal server error
schema:
Expand Down
22 changes: 11 additions & 11 deletions internal/sms-gateway/handlers/3rdparty.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (h *thirdPartyHandler) getDevice(user models.User, c *fiber.Ctx) error {
// @Success 202 {object} smsgateway.MessageState "Message enqueued"
// @Failure 400 {object} smsgateway.ErrorResponse "Invalid request"
// @Failure 401 {object} smsgateway.ErrorResponse "Unauthorized"
// @Failure 409 {object} smsgateway.ErrorResponse "Message with such ID already exists"
// @Failure 500 {object} smsgateway.ErrorResponse "Internal server error"
// @Header 202 {string} Location "Get message state URL"
// @Router /3rdparty/v1/message [post]
Expand All @@ -104,37 +105,36 @@ func (h *thirdPartyHandler) postMessage(user models.User, c *fiber.Ctx) error {
if err := h.BodyParserValidator(c, &req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
if err := req.Validate(); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}

skipPhoneValidation := c.QueryBool("skipPhoneValidation", false)

devices, err := h.devicesSvc.Select(devices.WithUserID(user.ID))
if err != nil {
return fmt.Errorf("can't select devices: %w", err)
h.Logger.Error("Failed to select devices", zap.Error(err), zap.String("user_id", user.ID))
return fiber.NewError(fiber.StatusInternalServerError, "Can't select devices. Please contact support")
}

if len(devices) < 1 {
return fiber.NewError(fiber.StatusBadRequest, "Нет ни одного устройства в учетной записи")
return fiber.NewError(fiber.StatusBadRequest, "No devices registered")
}

device := devices[0]
state, err := h.messagesSvc.Enqeue(device, req, messages.EnqueueOptions{SkipPhoneValidation: skipPhoneValidation})
if err != nil {
var err400 messages.ErrValidation
if errors.As(err, &err400) {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
var errValidation messages.ErrValidation
if isBadRequest := errors.As(err, &errValidation); isBadRequest {
return fiber.NewError(fiber.StatusBadRequest, errValidation.Error())
}
if isConflict := errors.Is(err, messages.ErrMessageAlreadyExists); isConflict {
return fiber.NewError(fiber.StatusConflict, err.Error())
}

return err
}

location, err := c.GetRouteURL(route3rdPartyGetMessage, fiber.Map{
"id": state.ID,
})
if err != nil {
h.Logger.Error("Failed to get route URL", zap.String("route", route3rdPartyGetMessage), zap.Error(err))
h.Logger.Warn("Failed to get route URL", zap.String("route", route3rdPartyGetMessage), zap.Error(err))
} else {
c.Location(location)
}
Expand Down
2 changes: 2 additions & 0 deletions internal/sms-gateway/modules/messages/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ func (e ErrValidation) Error() string {
return string(e)
}

var ErrMessageAlreadyExists = repositories.ErrMessageAlreadyExists

type EnqueueOptions struct {
SkipPhoneValidation bool
}
Expand Down
12 changes: 11 additions & 1 deletion internal/sms-gateway/repositories/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"errors"

"github.com/capcom6/sms-gateway/internal/sms-gateway/models"
"github.com/go-sql-driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)

const HashingLockName = "36444143-1ace-4dbf-891c-cc505911497e"

var ErrMessageNotFound = gorm.ErrRecordNotFound
var ErrMessageAlreadyExists = errors.New("duplicate id")

type MessagesRepository struct {
db *gorm.DB
Expand Down Expand Up @@ -54,7 +56,15 @@ func (r *MessagesRepository) Get(ID string, filter MessagesSelectFilter, options
}

func (r *MessagesRepository) Insert(message *models.Message) error {
return r.db.Omit("Device").Create(message).Error
err := r.db.Omit("Device").Create(message).Error
if err == nil {
return nil
}

if mysqlErr := err.(*mysql.MySQLError); mysqlErr != nil && mysqlErr.Number == 1062 {
return ErrMessageAlreadyExists
}
return err
}

func (r *MessagesRepository) UpdateState(message *models.Message) error {
Expand Down

0 comments on commit f395a96

Please sign in to comment.