Manager: avoid double-logging errors in job compiler scripts

Return a custom error type from `VM.getCompileJob()`, so that underlying
errors can be wrapped and more info can be given to the caller. This
replaces a local logger call, preventing both the function and its
caller logging the same error.
This commit is contained in:
Sybren A. Stüvel 2025-02-10 12:04:19 +01:00
parent 10b91422cc
commit e3d5d6b041

View File

@ -24,7 +24,6 @@ import (
) )
var ErrJobTypeUnknown = errors.New("job type unknown") var ErrJobTypeUnknown = errors.New("job type unknown")
var ErrScriptIncomplete = errors.New("job compiler script incomplete")
var ErrJobTypeBadEtag = errors.New("job type etag does not match") var ErrJobTypeBadEtag = errors.New("job type etag does not match")
// Service contains job compilers defined in JavaScript. // Service contains job compilers defined in JavaScript.
@ -191,12 +190,10 @@ func (s *Service) GetJobType(typeName string) (api.AvailableJobType, error) {
func (vm *VM) getCompileJob() (jobCompileFunc, error) { func (vm *VM) getCompileJob() (jobCompileFunc, error) {
compileJob, isCallable := goja.AssertFunction(vm.runtime.Get("compileJob")) compileJob, isCallable := goja.AssertFunction(vm.runtime.Get("compileJob"))
if !isCallable { if !isCallable {
// TODO: construct a more elaborate Error type that contains this info, instead of logging here. return nil, JobScriptIncompleteError{
log.Error(). scriptFilename: vm.compiler.filename,
Str("jobType", vm.compiler.jobType). message: "does not define a compileJob(job) function",
Str("script", vm.compiler.filename). }
Msg("script does not define a compileJob(job) function")
return nil, ErrScriptIncomplete
} }
// TODO: wrap this in a nicer way. // TODO: wrap this in a nicer way.
@ -206,18 +203,39 @@ func (vm *VM) getCompileJob() (jobCompileFunc, error) {
}, nil }, nil
} }
type JobScriptIncompleteError struct {
wrappedErr error
scriptFilename string
message string
}
func (err JobScriptIncompleteError) Error() string {
if err.wrappedErr == nil {
return fmt.Sprintf("script (%s) %s", err.scriptFilename, err.message)
}
return fmt.Sprintf("script (%s) %s: %v", err.scriptFilename, err.message, err.wrappedErr)
}
func (err JobScriptIncompleteError) Unwrap() error {
return err.wrappedErr
}
func (vm *VM) getJobTypeInfo() (api.AvailableJobType, error) { func (vm *VM) getJobTypeInfo() (api.AvailableJobType, error) {
jtValue := vm.runtime.Get("JOB_TYPE") jtValue := vm.runtime.Get("JOB_TYPE")
if jtValue == nil {
return api.AvailableJobType{}, JobScriptIncompleteError{
scriptFilename: vm.compiler.filename,
message: "does not define a JOB_TYPE object",
}
}
var ajt api.AvailableJobType var ajt api.AvailableJobType
if err := vm.runtime.ExportTo(jtValue, &ajt); err != nil { if err := vm.runtime.ExportTo(jtValue, &ajt); err != nil {
// TODO: construct a more elaborate Error type that contains this info, instead of logging here. return api.AvailableJobType{}, JobScriptIncompleteError{
log.Error(). wrappedErr: err,
Err(err). scriptFilename: vm.compiler.filename,
Str("jobType", vm.compiler.jobType). message: "does not define a proper JOB_TYPE object",
Str("script", vm.compiler.filename). }
Msg("script does not define a proper JOB_TYPE object")
return api.AvailableJobType{}, ErrScriptIncomplete
} }
ajt.Name = vm.compiler.jobType ajt.Name = vm.compiler.jobType