Merged in bugfix/errhandling (pull request #89)

Error handling

* basic
This commit is contained in:
Michael McGuinness
2025-03-05 19:49:03 +00:00
parent c78ca26a6f
commit 8f409e60a8
36 changed files with 965 additions and 641 deletions
+9 -5
View File
@@ -3,6 +3,7 @@ package queryrunner
import (
"context"
"encoding/json"
"log/slog"
resultset "queryorchestration/internal/query/result/set"
@@ -35,16 +36,18 @@ type Body struct {
QueryID uuid.UUID `json:"query_id" validate:"required,uuid"`
}
func (s *Runner) Process(ctx context.Context, req *types.Message) error {
func (s *Runner) Process(ctx context.Context, req *types.Message) bool {
var body Body
err := json.Unmarshal([]byte(*req.Body), &body)
if err != nil {
return err
slog.Error("parsing body", "messageId", *req.MessageId, "body", *req.Body)
return true
}
err = s.validator.Struct(body)
if err != nil {
return err
slog.Error("invalid body", "messageId", *req.MessageId, "error", err)
return true
}
err = s.svc.ResultSet.Set(ctx, &resultset.Set{
@@ -52,8 +55,9 @@ func (s *Runner) Process(ctx context.Context, req *types.Message) error {
QueryID: body.QueryID,
})
if err != nil {
return err
slog.Error("unable to process", "error", err)
return false
}
return nil
return true
}
+85 -74
View File
@@ -58,85 +58,96 @@ func TestQueryRunner(t *testing.T) {
})
assert.NotNil(t, runner)
doc := resultset.Set{
DocumentID: uuid.New(),
QueryID: uuid.New(),
}
bodyBytes, err := json.Marshal(doc)
assert.NoError(t, err)
body := string(bodyBytes)
msg := &types.Message{
Body: &body,
}
t.Run("valid", func(t *testing.T) {
doc := resultset.Set{
DocumentID: uuid.New(),
QueryID: uuid.New(),
}
bodyBytes, err := json.Marshal(doc)
assert.NoError(t, err)
body := string(bodyBytes)
msg := &types.Message{
Body: &body,
}
qcfg := "{\"path\":\"examplekey\"}"
query := &resultprocessor.Query{
ID: doc.QueryID,
Version: 2,
RequiredQueryIDs: &[]uuid.UUID{uuid.New()},
Config: &qcfg,
}
params := &resultset.Set{
DocumentID: doc.DocumentID,
}
qcfg := "{\"path\":\"examplekey\"}"
query := &resultprocessor.Query{
ID: doc.QueryID,
Version: 2,
RequiredQueryIDs: &[]uuid.UUID{uuid.New()},
Config: &qcfg,
}
params := &resultset.Set{
DocumentID: doc.DocumentID,
}
cleanEntryId := uuid.New()
textEntryId := uuid.New()
pool.ExpectQuery("name: GetDocumentTextEntry :one").WithArgs(database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "documentId", "bucket", "key", "version", "cleanEntryId"}).
AddRow(database.MustToDBUUID(textEntryId), database.MustToDBUUID(params.DocumentID), "buket", "/i/am/here", int32(1), database.MustToDBUUID(cleanEntryId)),
cleanEntryId := uuid.New()
textEntryId := uuid.New()
pool.ExpectQuery("name: GetTextEntryByDocId :one").WithArgs(database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "documentId", "bucket", "key", "version", "cleanEntryId"}).
AddRow(database.MustToDBUUID(textEntryId), database.MustToDBUUID(params.DocumentID), "buket", "/i/am/here", int32(1), database.MustToDBUUID(cleanEntryId)),
)
pool.ExpectQuery("name: GetQuery :one").WithArgs(database.MustToDBUUID(query.ID)).WillReturnRows(
pgxmock.NewRows([]string{"id", "type", "activeVersion", "latestVersion", "config", "requiredIds"}).
AddRow(database.MustToDBUUID(query.ID), repository.QuerytypeJsonExtractor, query.Version, query.Version, []byte(*query.Config), database.MustToDBUUIDArray(*query.RequiredQueryIDs)),
)
pool.ExpectQuery("name: GetQuery :one").WithArgs(database.MustToDBUUID(query.ID)).WillReturnRows(
pgxmock.NewRows([]string{"id", "type", "activeVersion", "latestVersion", "config", "requiredIds"}).
AddRow(database.MustToDBUUID(query.ID), repository.QuerytypeJsonExtractor, query.Version, query.Version, []byte(*query.Config), database.MustToDBUUIDArray(*query.RequiredQueryIDs)),
)
pool.ExpectQuery("name: GetQueryWithVersion :one").WithArgs(database.MustToDBUUID(query.ID), &query.Version).WillReturnRows(
pgxmock.NewRows([]string{"id", "type", "activeVersion", "latestVersion", "config", "requiredIds"}).
AddRow(database.MustToDBUUID(query.ID), repository.QuerytypeJsonExtractor, query.Version, query.Version, []byte(*query.Config), database.MustToDBUUIDArray(*query.RequiredQueryIDs)),
)
requiredResultId := uuid.New()
strVal := "{\"examplekey\":\"example_value\"}"
pool.ExpectQuery("name: ListQueryRequirementValues :many").WithArgs(database.MustToDBUUID(query.ID), &query.Version, database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "type", "value"}).
AddRow(database.MustToDBUUID(requiredResultId), database.MustToDBUUID((*query.RequiredQueryIDs)[0]), repository.QuerytypeContextFull, &strVal),
pool.ExpectQuery("name: GetQueryWithVersion :one").WithArgs(database.MustToDBUUID(query.ID), &query.Version).WillReturnRows(
pgxmock.NewRows([]string{"id", "type", "activeVersion", "latestVersion", "config", "requiredIds"}).
AddRow(database.MustToDBUUID(query.ID), repository.QuerytypeJsonExtractor, query.Version, query.Version, []byte(*query.Config), database.MustToDBUUIDArray(*query.RequiredQueryIDs)),
)
pool.ExpectQuery("name: GetActiveQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID)).WillReturnRows(
pgxmock.NewRows([]string{"config"}).
AddRow([]byte(qcfg)),
)
pool.ExpectBegin()
resultId := uuid.New()
pool.ExpectQuery("name: AddResult :one").WithArgs(database.MustToDBUUID(query.ID), pgxmock.AnyArg(), database.MustToDBUUID(textEntryId), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(database.MustToDBUUID(resultId)),
)
pool.ExpectQuery("name: ListQueryRequirementValues :many").WithArgs(database.MustToDBUUID(query.ID), &query.Version, database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "type", "value"}).
AddRow(database.MustToDBUUID(requiredResultId), database.MustToDBUUID((*query.RequiredQueryIDs)[0]), repository.QuerytypeContextFull, &strVal),
)
pool.ExpectExec("name: AddResultDependency :exec").WithArgs(database.MustToDBUUID(resultId), database.MustToDBUUID(requiredResultId)).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(database.MustToDBUUID(query.ID), database.MustToDBUUID(doc.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"queryId"}).
AddRow(database.MustToDBUUID((*query.RequiredQueryIDs)[0])),
requiredResultId := uuid.New()
strVal := "{\"examplekey\":\"example_value\"}"
pool.ExpectQuery("name: ListQueryRequirementValues :many").WithArgs(database.MustToDBUUID(query.ID), &query.Version, database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "type", "value"}).
AddRow(database.MustToDBUUID(requiredResultId), database.MustToDBUUID((*query.RequiredQueryIDs)[0]), repository.QuerytypeContextFull, &strVal),
)
pool.ExpectQuery("name: GetActiveQueryConfig :one").WithArgs(database.MustToDBUUID(query.ID)).WillReturnRows(
pgxmock.NewRows([]string{"config"}).
AddRow([]byte(qcfg)),
)
pool.ExpectBegin()
resultId := uuid.New()
pool.ExpectQuery("name: AddResult :one").WithArgs(database.MustToDBUUID(query.ID), pgxmock.AnyArg(), database.MustToDBUUID(textEntryId), query.Version).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(database.MustToDBUUID(resultId)),
)
pool.ExpectQuery("name: ListQueryRequirementValues :many").WithArgs(database.MustToDBUUID(query.ID), &query.Version, database.MustToDBUUID(params.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"id", "queryId", "type", "value"}).
AddRow(database.MustToDBUUID(requiredResultId), database.MustToDBUUID((*query.RequiredQueryIDs)[0]), repository.QuerytypeContextFull, &strVal),
)
pool.ExpectExec("name: AddResultDependency :exec").WithArgs(database.MustToDBUUID(resultId), database.MustToDBUUID(requiredResultId)).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
pool.ExpectQuery("name: ListQueryDirectDependentsByDocumentID :many").WithArgs(database.MustToDBUUID(query.ID), database.MustToDBUUID(doc.DocumentID)).
WillReturnRows(
pgxmock.NewRows([]string{"queryId"}).
AddRow(database.MustToDBUUID((*query.RequiredQueryIDs)[0])),
)
mockSQS.EXPECT().
SendMessage(
mock.Anything,
mock.MatchedBy(func(in *sqs.SendMessageInput) bool {
return *in.QueueUrl == cfg.QueryURL && *in.MessageBody == fmt.Sprintf("{\"document_id\":\"%s\",\"query_id\":\"%s\"}", params.DocumentID.String(), (*query.RequiredQueryIDs)[0].String())
}),
mock.Anything,
).
Return(&sqs.SendMessageOutput{}, nil)
mockSQS.EXPECT().
SendMessage(
mock.Anything,
mock.MatchedBy(func(in *sqs.SendMessageInput) bool {
return *in.QueueUrl == cfg.QueryURL && *in.MessageBody == fmt.Sprintf("{\"document_id\":\"%s\",\"query_id\":\"%s\"}", params.DocumentID.String(), (*query.RequiredQueryIDs)[0].String())
}),
mock.Anything,
).
Return(&sqs.SendMessageOutput{}, nil)
err = runner.Process(ctx, msg)
assert.NoError(t, err)
assert.True(t, runner.Process(ctx, msg))
})
t.Run("invalid body", func(t *testing.T) {
body := "definitely invalid"
msgId := "id"
msg := &types.Message{
Body: &body,
MessageId: &msgId,
}
assert.True(t, runner.Process(ctx, msg))
})
}