fix(question): 图片上传失败时回滚已创建的提问
Questions.Create 在图片处理之前就提交了,失败分支只渲染错误页、不回滚。于是: 箱主收到一条无图提问,提问者只看到「图片过大 / 上传失败」以为没发出去;再想重发 又会被 DuplicateGuard 按「同 IP + 同内容 5 分钟内重复」拦住 —— 既没发成功也重发不了。 现在失败分支先 Questions.DeleteByID 回滚(连带清理追问与图片关联,并回退前面 那次提问配额 +1),再做提示。顺带把不需要的 else 去掉(两个分支都以 return 结束)。 验证:6MB 图提交后提问数增量 0、该行 deleted_at 非空(回滚走的是软删); 无图对照增量 1。两条路径均返回 200,正常流程未受影响。
This commit is contained in:
+11
-2
@@ -685,18 +685,27 @@ func New(ctx context.Context, f form.NewQuestion, pageUser *db.User, recaptcha r
|
|||||||
QuestionID: question.ID,
|
QuestionID: question.ID,
|
||||||
UploaderUserID: askerUserID,
|
UploaderUserID: askerUserID,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
// 问题在上面已经落库(db.Questions.Create),图片这一步失败必须回滚。
|
||||||
|
// 不回滚的后果不是「少一张图」:箱主会收到一条无图提问,而提问者只看到
|
||||||
|
// 「图片过大 / 上传失败」,以为没发出去;再想重发又会被 DuplicateGuard
|
||||||
|
// 按「同 IP + 同内容 5 分钟内重复」拦住 —— 既没发成功也重发不了。
|
||||||
|
// DeleteByID 会连带清理追问与图片关联,并回退前面那次提问配额(+1)。
|
||||||
|
if delErr := db.Questions.DeleteByID(ctx.Request().Context(), question.ID); delErr != nil {
|
||||||
|
logrus.WithContext(ctx.Request().Context()).WithError(delErr).Errorf(
|
||||||
|
"图片上传失败后回滚提问 %d 失败,已留下一条无图提问", question.ID)
|
||||||
|
}
|
||||||
|
|
||||||
if errors.Is(err, ErrUploadImageSizeTooLarge) || errors.Is(err, imagecheck.ErrImageTooLarge) {
|
if errors.Is(err, ErrUploadImageSizeTooLarge) || errors.Is(err, imagecheck.ErrImageTooLarge) {
|
||||||
ctx.SetError(errors.New(i18n.T(ctx.Lang(), "question.errImageTooLarge")), f)
|
ctx.SetError(errors.New(i18n.T(ctx.Lang(), "question.errImageTooLarge")), f)
|
||||||
ctx.Success("question/list")
|
ctx.Success("question/list")
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to upload image")
|
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to upload image")
|
||||||
ctx.SetError(errors.New(i18n.T(ctx.Lang(), "question.errUploadImageFailed")), f)
|
ctx.SetError(errors.New(i18n.T(ctx.Lang(), "question.errUploadImageFailed")), f)
|
||||||
ctx.Success("question/list")
|
ctx.Success("question/list")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if err := db.Questions.UpdateCensor(ctx.Request().Context(), question.ID, db.UpdateQuestionCensorOptions{
|
if err := db.Questions.UpdateCensor(ctx.Request().Context(), question.ID, db.UpdateQuestionCensorOptions{
|
||||||
ContentCensorMetadata: censorResponse.ToJSON(),
|
ContentCensorMetadata: censorResponse.ToJSON(),
|
||||||
|
|||||||
Reference in New Issue
Block a user