FIX: Uploading File With Unkown Catagory Id
Build, Push and Deploy CMS / build-push-deploy (push) Successful in 2m22s

This commit is contained in:
FahdShalhoub
2026-08-27 18:43:04 +03:00
parent ae129c8f61
commit b68086eea4
5 changed files with 51 additions and 9 deletions
+7 -1
View File
@@ -78,8 +78,14 @@ const docTemplate = `{
"$ref": "#/definitions/api.ProblemDetails"
}
},
"404": {
"description": "categoryIds referenced a category that does not exist",
"schema": {
"$ref": "#/definitions/api.ProblemDetails"
}
},
"422": {
"description": "title was empty, key was missing or not a key issued by this API, or categoryIds was empty or contained an id that does not exist",
"description": "title was empty, key was missing or not a key issued by this API, or categoryIds was empty",
"schema": {
"$ref": "#/definitions/api.ProblemDetails"
}
+7 -1
View File
@@ -71,8 +71,14 @@
"$ref": "#/definitions/api.ProblemDetails"
}
},
"404": {
"description": "categoryIds referenced a category that does not exist",
"schema": {
"$ref": "#/definitions/api.ProblemDetails"
}
},
"422": {
"description": "title was empty, key was missing or not a key issued by this API, or categoryIds was empty or contained an id that does not exist",
"description": "title was empty, key was missing or not a key issued by this API, or categoryIds was empty",
"schema": {
"$ref": "#/definitions/api.ProblemDetails"
}
+5 -1
View File
@@ -186,9 +186,13 @@ paths:
description: Request body was not valid JSON
schema:
$ref: '#/definitions/api.ProblemDetails'
"404":
description: categoryIds referenced a category that does not exist
schema:
$ref: '#/definitions/api.ProblemDetails'
"422":
description: title was empty, key was missing or not a key issued by this
API, or categoryIds was empty or contained an id that does not exist
API, or categoryIds was empty
schema:
$ref: '#/definitions/api.ProblemDetails'
"500":
+16
View File
@@ -0,0 +1,16 @@
package handlers
import "errors"
// Sentinel errors the handlers branch on with errors.Is to decide which
// problem response a failure deserves. They exist to separate a client's
// mistake from a server fault where the code that detects both is the same
// code — the repositories return plain errors, so without these every failure
// out of a lookup would have to be answered as a 500.
// errUnknownCatagoryID reports that a submitted category id is not in the
// category table. It is kept distinct from the error the lookup itself
// returns because the two are not the same kind of failure: an id nobody has
// is the client's mistake and answers 404, while a lookup that could not run
// is the server's and answers 500.
var errUnknownCatagoryID = errors.New("unknown catagory id")
+16 -6
View File
@@ -5,6 +5,7 @@ import (
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
@@ -111,7 +112,8 @@ func PresignVideoUpload(w http.ResponseWriter, r *http.Request) {
// @Param request body api.CompleteRequest true "Video metadata plus the storage key from the presign step. title, key and categoryIds are required; categoryIds must hold at least one id from GET /api/categories."
// @Success 201 {object} api.CompleteResponse
// @Failure 400 {object} api.ProblemDetails "Request body was not valid JSON"
// @Failure 422 {object} api.ProblemDetails "title was empty, key was missing or not a key issued by this API, or categoryIds was empty or contained an id that does not exist"
// @Failure 404 {object} api.ProblemDetails "categoryIds referenced a category that does not exist"
// @Failure 422 {object} api.ProblemDetails "title was empty, key was missing or not a key issued by this API, or categoryIds was empty"
// @Failure 500 {object} api.ProblemDetails "Categories could not be read, the transcoding job could not be queued, or the video record could not be saved"
// @Router /api/videos [post]
func CompleteVideoUpload(w http.ResponseWriter, r *http.Request) {
@@ -151,7 +153,12 @@ func CompleteVideoUpload(w http.ResponseWriter, r *http.Request) {
return
}
err := validateCatagoryIDS(r.Context(), req.CategoryIDs)
unknownCatagoryID, err := validateCatagoryIDS(r.Context(), req.CategoryIDs)
if errors.Is(err, errUnknownCatagoryID) {
writeProblem(w, http.StatusNotFound, "Catagory Does Not Exist",
fmt.Sprintf("The 'categoryIds' field referenced the id %d, which no category has. Send only ids taken from the 'id' field of GET /api/categories. No video record was created and no transcoding job was queued; the uploaded file is still in storage, so retry this request with the same 'key'.", unknownCatagoryID))
return
}
if err != nil {
log.Printf("Something Went Wrong Loading Categories: %s", err)
writeProblem(w, http.StatusInternalServerError, "Something Went Wrong Loading Categories",
@@ -201,19 +208,22 @@ func CompleteVideoUpload(w http.ResponseWriter, r *http.Request) {
})
}
func validateCatagoryIDS(ctx context.Context, submitted []int16) (err error) {
// validateCatagoryIDS checks every submitted id against the category table. On
// the first id that has no category it returns that id alongside
// errUnknownCatagoryID, so the handler can name it in the response.
func validateCatagoryIDS(ctx context.Context, submitted []int16) (int16, error) {
categoryIDS, err := repositories.CatagoriesRepo.ListCategoriesIDs(ctx)
if err != nil {
return err
return 0, err
}
for _, submittedID := range submitted {
if !slices.Contains(categoryIDS, submittedID) {
return fmt.Errorf("Incorrect Category IDs")
return submittedID, errUnknownCatagoryID
}
}
return nil
return 0, nil
}
func randomFilename(original string) (string, error) {