fs/rc/jobs: ExecuteJob propagate the error returned by function

Without this patch the resulting error is first converted to string and then recreated.
This makes it impossible to use the defined error types to figure out the cause of the error,
and may result in invalid HTTP status codes.

This patch adds a test TestExecuteJobErrorPropagation to validate that the errors are
properly propagated.
This commit is contained in:
Michał Matczuk 2019-08-21 14:50:18 +02:00 committed by Nick Craig-Wood
parent 341d880027
commit 3247e69cf5
2 changed files with 19 additions and 5 deletions

View File

@ -29,6 +29,11 @@ type Job struct {
Duration float64 `json:"duration"` Duration float64 `json:"duration"`
Output rc.Params `json:"output"` Output rc.Params `json:"output"`
Stop func() `json:"-"` Stop func() `json:"-"`
// realErr is the Error before printing it as a string, it's used to return
// the real error to the upper application layers while still printing the
// string error message.
realErr error
} }
// Jobs describes a collection of running tasks // Jobs describes a collection of running tasks
@ -122,9 +127,11 @@ func (job *Job) finish(out rc.Params, err error) {
job.Output = out job.Output = out
job.Duration = job.EndTime.Sub(job.StartTime).Seconds() job.Duration = job.EndTime.Sub(job.StartTime).Seconds()
if err != nil { if err != nil {
job.realErr = err
job.Error = err.Error() job.Error = err.Error()
job.Success = false job.Success = false
} else { } else {
job.realErr = nil
job.Error = "" job.Error = ""
job.Success = true job.Success = true
} }
@ -221,11 +228,7 @@ func StartAsyncJob(fn rc.Func, in rc.Params) (rc.Params, error) {
func ExecuteJob(ctx context.Context, fn rc.Func, in rc.Params) (rc.Params, int64, error) { func ExecuteJob(ctx context.Context, fn rc.Func, in rc.Params) (rc.Params, int64, error) {
job, ctx := running.NewSyncJob(ctx, in) job, ctx := running.NewSyncJob(ctx, in)
job.run(ctx, fn, in) job.run(ctx, fn, in)
var err error return job.Output, job.ID, job.realErr
if !job.Success {
err = errors.New(job.Error)
}
return job.Output, job.ID, err
} }
func init() { func init() {

View File

@ -213,6 +213,17 @@ func TestExecuteJob(t *testing.T) {
assert.Equal(t, int64(1), id) assert.Equal(t, int64(1), id)
} }
func TestExecuteJobErrorPropagation(t *testing.T) {
jobID = 0
testErr := errors.New("test error")
errorFn := func(ctx context.Context, in rc.Params) (out rc.Params, err error) {
return nil, testErr
}
_, _, err := ExecuteJob(context.Background(), errorFn, rc.Params{})
assert.Equal(t, testErr, err)
}
func TestRcJobStatus(t *testing.T) { func TestRcJobStatus(t *testing.T) {
jobID = 0 jobID = 0
_, err := StartAsyncJob(longFn, rc.Params{}) _, err := StartAsyncJob(longFn, rc.Params{})