From 88cb47d948ce54f1b42af638ce2332a947f23e13 Mon Sep 17 00:00:00 2001 From: mdrakos Date: Fri, 25 Aug 2023 12:55:55 -0700 Subject: [PATCH 1/2] Update runtime-debug error handling --- pkg/platform/api/buildplanner/model/buildplan.go | 5 +++++ pkg/platform/model/buildplanner.go | 2 +- pkg/platform/runtime/runtime.go | 7 ++++++- pkg/platform/runtime/setup/setup.go | 16 +++++++++++++--- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pkg/platform/api/buildplanner/model/buildplan.go b/pkg/platform/api/buildplanner/model/buildplan.go index 8c7f64b137..ae69db29a3 100644 --- a/pkg/platform/api/buildplanner/model/buildplan.go +++ b/pkg/platform/api/buildplanner/model/buildplan.go @@ -92,6 +92,7 @@ func (o Operation) String() string { } type BuildPlannerError struct { + Err error ValidationErrors []string IsTransient bool } @@ -111,6 +112,10 @@ func (e *BuildPlannerError) UserError() string { } func (e *BuildPlannerError) Error() string { + if e.Err != nil { + return e.Err.Error() + } + // Append last five lines to error message offset := 0 numLines := len(e.ValidationErrors) diff --git a/pkg/platform/model/buildplanner.go b/pkg/platform/model/buildplanner.go index e6d72eee51..0939e6f70b 100644 --- a/pkg/platform/model/buildplanner.go +++ b/pkg/platform/model/buildplanner.go @@ -370,7 +370,7 @@ func processBuildPlannerError(bpErr error, fallbackMessage string) error { return locale.NewInputError("err_buildplanner_deprecated", "Encountered deprecation error: {{.V0}}", graphqlErr.Message) } } - return errs.Wrap(bpErr, fallbackMessage) + return &bpModel.BuildPlannerError{Err: errs.Wrap(bpErr, fallbackMessage)} } var versionRe = regexp.MustCompile(`^\d+(\.\d+)*$`) diff --git a/pkg/platform/runtime/runtime.go b/pkg/platform/runtime/runtime.go index 95a2a7b813..b5eb63d17d 100644 --- a/pkg/platform/runtime/runtime.go +++ b/pkg/platform/runtime/runtime.go @@ -192,7 +192,7 @@ func (r *Runtime) recordCompletion(err error) { errorType = "input" case errs.Matches(err, &model.SolverError{}): errorType = "solve" - case errs.Matches(err, &setup.BuildError{}) || errs.Matches(err, &buildlog.BuildError{}): + case errs.Matches(err, &setup.BuildError{}), errs.Matches(err, &buildlog.BuildError{}): errorType = "build" case errs.Matches(err, &bpModel.BuildPlannerError{}): errorType = "buildplan" @@ -206,6 +206,9 @@ func (r *Runtime) recordCompletion(err error) { case errs.Matches(err, &setup.ArtifactInstallError{}): errorType = "install" // Note: do not break because there could be download errors, and those take precedence + case errs.Matches(err, &setup.BuildError{}), errs.Matches(err, &buildlog.BuildError{}): + errorType = "build" + break // it only takes one build failure to report the runtime failure as due to build error } } } @@ -213,6 +216,8 @@ func (r *Runtime) recordCompletion(err error) { // and those errors actually caused the failure, not these. case errs.Matches(err, &setup.ProgressReportError{}) || errs.Matches(err, &buildlog.EventHandlerError{}): errorType = "progress" + case errs.Matches(err, &setup.ExecutorSetupError{}): + errorType = "postprocess" } var message string diff --git a/pkg/platform/runtime/setup/setup.go b/pkg/platform/runtime/setup/setup.go index 15b85b36f6..51049739a2 100644 --- a/pkg/platform/runtime/setup/setup.go +++ b/pkg/platform/runtime/setup/setup.go @@ -79,6 +79,10 @@ type ArtifactSetupErrors struct { errs []error } +type ExecutorSetupError struct { + *errs.WrapperError +} + func (a *ArtifactSetupErrors) Error() string { var errors []string for _, err := range a.errs { @@ -189,7 +193,7 @@ func (s *Setup) Update() (rerr error) { // Update executors if err := s.updateExecutors(artifacts); err != nil { - return errs.Wrap(err, "Failed to update executors") + return ExecutorSetupError{errs.Wrap(err, "Failed to update executors")} } // Mark installation as completed @@ -745,12 +749,16 @@ func (s *Setup) moveToInstallPath(a artifact.ArtifactID, unpackedDir string, env func (s *Setup) downloadArtifact(a artifact.ArtifactDownload, targetFile string) (rerr error) { defer func() { if rerr != nil { - rerr = &ArtifactDownloadError{errs.Wrap(rerr, "Unable to download artifact")} + if !errs.Matches(rerr, &ProgressReportError{}) { + rerr = &ArtifactDownloadError{errs.Wrap(rerr, "Unable to download artifact")} + } + if err := s.handleEvent(events.ArtifactDownloadFailure{a.ArtifactID, rerr}); err != nil { rerr = errs.Wrap(rerr, "Could not handle ArtifactDownloadFailure event") return } } + if err := s.handleEvent(events.ArtifactDownloadSuccess{a.ArtifactID}); err != nil { rerr = errs.Wrap(rerr, "Could not handle ArtifactDownloadSuccess event") return @@ -765,7 +773,7 @@ func (s *Setup) downloadArtifact(a artifact.ArtifactDownload, targetFile string) b, err := httputil.GetWithProgress(artifactURL.String(), &progress.Report{ ReportSizeCb: func(size int) error { if err := s.handleEvent(events.ArtifactDownloadStarted{a.ArtifactID, size}); err != nil { - return errs.Wrap(err, "Could not handle ArtifactDownloadStarted event") + return ProgressReportError{errs.Wrap(err, "Could not handle ArtifactDownloadStarted event")} } return nil }, @@ -779,9 +787,11 @@ func (s *Setup) downloadArtifact(a artifact.ArtifactDownload, targetFile string) if err != nil { return errs.Wrap(err, "Download %s failed", artifactURL.String()) } + if err := fileutils.WriteFile(targetFile, b); err != nil { return errs.Wrap(err, "Writing download to target file %s failed", targetFile) } + return nil } From 72aecd649e6a3e7468f43a10a88896aa5cd46c1b Mon Sep 17 00:00:00 2001 From: mdrakos Date: Tue, 29 Aug 2023 13:09:15 -0700 Subject: [PATCH 2/2] Make deprecation errors also buildplanner errors --- pkg/platform/model/buildplanner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/platform/model/buildplanner.go b/pkg/platform/model/buildplanner.go index 0939e6f70b..cddded07d7 100644 --- a/pkg/platform/model/buildplanner.go +++ b/pkg/platform/model/buildplanner.go @@ -367,7 +367,7 @@ func processBuildPlannerError(bpErr error, fallbackMessage string) error { if errors.As(bpErr, graphqlErr) { code, ok := graphqlErr.Extensions[codeExtensionKey].(string) if ok && code == clientDeprecationErrorKey { - return locale.NewInputError("err_buildplanner_deprecated", "Encountered deprecation error: {{.V0}}", graphqlErr.Message) + return &bpModel.BuildPlannerError{Err: locale.NewInputError("err_buildplanner_deprecated", "Encountered deprecation error: {{.V0}}", graphqlErr.Message)} } } return &bpModel.BuildPlannerError{Err: errs.Wrap(bpErr, fallbackMessage)}