Skip to content

Commit

Permalink
Improve error messages for PostCSS etc.
Browse files Browse the repository at this point in the history
Fixes #9730
  • Loading branch information
bep committed Jul 17, 2023
1 parent c406fd3 commit 387c5f6
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 7 deletions.
25 changes: 24 additions & 1 deletion common/herrors/errors.go
Expand Up @@ -59,11 +59,34 @@ func GetGID() uint64 {
return n
}

// IsFeatureNotAvailableError returns true if the given error is or contains a FeatureNotAvailableError.
func IsFeatureNotAvailableError(err error) bool {
return errors.Is(err, &FeatureNotAvailableError{})
}

// ErrFeatureNotAvailable denotes that a feature is unavailable.
//
// We will, at least to begin with, make some Hugo features (SCSS with libsass) optional,
// and this error is used to signal those situations.
var ErrFeatureNotAvailable = errors.New("this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information")
var ErrFeatureNotAvailable = &FeatureNotAvailableError{Cause: errors.New("this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information")}

// FeatureNotAvailableError is an error type used to signal that a feature is not available.
type FeatureNotAvailableError struct {
Cause error
}

func (e *FeatureNotAvailableError) Unwrap() error {
return e.Cause
}

func (e *FeatureNotAvailableError) Error() string {
return e.Cause.Error()
}

func (e *FeatureNotAvailableError) Is(target error) bool {
_, ok := target.(*FeatureNotAvailableError)
return ok
}

// Must panics if err != nil.
func Must(err error) {
Expand Down
10 changes: 10 additions & 0 deletions common/herrors/errors_test.go
Expand Up @@ -14,6 +14,7 @@
package herrors

import (
"errors"
"fmt"
"testing"

Expand All @@ -34,3 +35,12 @@ func TestIsNotExist(t *testing.T) {
// os.IsNotExist returns false for wrapped errors.
c.Assert(IsNotExist(fmt.Errorf("foo: %w", afero.ErrFileNotFound)), qt.Equals, true)
}

func TestIsFeatureNotAvailableError(t *testing.T) {
c := qt.New(t)

c.Assert(IsFeatureNotAvailableError(ErrFeatureNotAvailable), qt.Equals, true)
c.Assert(IsFeatureNotAvailableError(&FeatureNotAvailableError{}), qt.Equals, true)
c.Assert(IsFeatureNotAvailableError(errors.New("asdf")), qt.Equals, false)

}
2 changes: 1 addition & 1 deletion config/commonConfig.go
Expand Up @@ -148,7 +148,7 @@ func (b BuildConfig) UseResourceCache(err error) bool {
}

if b.UseResourceCacheWhen == "fallback" {
return err == herrors.ErrFeatureNotAvailable
return herrors.IsFeatureNotAvailableError(err)
}

return true
Expand Down
4 changes: 2 additions & 2 deletions resources/resource_transformers/babel/babel.go
Expand Up @@ -181,7 +181,7 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx
if err != nil {
if hexec.IsNotFound(err) {
// This may be on a CI server etc. Will fall back to pre-built assets.
return herrors.ErrFeatureNotAvailable
return &herrors.FeatureNotAvailableError{Cause: err}
}
return err
}
Expand All @@ -200,7 +200,7 @@ func (t *babelTransformation) Transform(ctx *resources.ResourceTransformationCtx
err = cmd.Run()
if err != nil {
if hexec.IsNotFound(err) {
return herrors.ErrFeatureNotAvailable
return &herrors.FeatureNotAvailableError{Cause: err}
}
return fmt.Errorf(errBuf.String()+": %w", err)
}
Expand Down
19 changes: 19 additions & 0 deletions resources/resource_transformers/postcss/integration_test.go
Expand Up @@ -168,6 +168,25 @@ func TestTransformPostCSSError(t *testing.T) {

}

func TestTransformPostCSSNotInstalledError(t *testing.T) {
if !htesting.IsCI() {
t.Skip("Skip long running test when running locally")
}

c := qt.New(t)

s, err := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: c,
NeedsOsFS: true,
TxtarString: postCSSIntegrationTestFiles,
}).BuildE()

s.AssertIsFileError(err)
c.Assert(err.Error(), qt.Contains, `binary with name "npx" not found`)

}

// #9895
func TestTransformPostCSSImportError(t *testing.T) {
if !htesting.IsCI() {
Expand Down
6 changes: 4 additions & 2 deletions resources/resource_transformers/postcss/postcss.go
Expand Up @@ -205,7 +205,7 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
if err != nil {
if hexec.IsNotFound(err) {
// This may be on a CI server etc. Will fall back to pre-built assets.
return herrors.ErrFeatureNotAvailable
return &herrors.FeatureNotAvailableError{Cause: err}
}
return err
}
Expand Down Expand Up @@ -240,7 +240,9 @@ func (t *postcssTransformation) Transform(ctx *resources.ResourceTransformationC
err = cmd.Run()
if err != nil {
if hexec.IsNotFound(err) {
return herrors.ErrFeatureNotAvailable
return &herrors.FeatureNotAvailableError{
Cause: err,
}
}
return imp.toFileError(errBuf.String())
}
Expand Down
2 changes: 1 addition & 1 deletion resources/transform.go
Expand Up @@ -449,7 +449,7 @@ func (r *resourceAdapter) transform(publish, setContent bool) error {
newErr := func(err error) error {
msg := fmt.Sprintf("%s: failed to transform %q (%s)", strings.ToUpper(tr.Key().Name), tctx.InPath, tctx.InMediaType.Type)

if err == herrors.ErrFeatureNotAvailable {
if herrors.IsFeatureNotAvailableError(err) {
var errMsg string
if tr.Key().Name == "postcss" {
// This transformation is not available in this
Expand Down

0 comments on commit 387c5f6

Please sign in to comment.