aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2023-07-17 19:15:48 +0200
committerBjørn Erik Pedersen <[email protected]>2023-07-17 20:42:32 +0200
commit387c5f60f97141d638327f84ee426fb44f6c554e (patch)
treedd9b40c4f33532183d2e84b8ea09e7dc72cb1b4a
parentc406fd3a0e0efa17f69095ca6317ba1036fc8964 (diff)
downloadhugo-387c5f60f97141d638327f84ee426fb44f6c554e.tar.gz
hugo-387c5f60f97141d638327f84ee426fb44f6c554e.zip
Improve error messages for PostCSS etc.
Fixes #9730
-rw-r--r--common/herrors/errors.go25
-rw-r--r--common/herrors/errors_test.go10
-rw-r--r--config/commonConfig.go2
-rw-r--r--resources/resource_transformers/babel/babel.go4
-rw-r--r--resources/resource_transformers/postcss/integration_test.go19
-rw-r--r--resources/resource_transformers/postcss/postcss.go6
-rw-r--r--resources/transform.go2
7 files changed, 61 insertions, 7 deletions
diff --git a/common/herrors/errors.go b/common/herrors/errors.go
index 4d8642362..598c50b32 100644
--- a/common/herrors/errors.go
+++ b/common/herrors/errors.go
@@ -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) {
diff --git a/common/herrors/errors_test.go b/common/herrors/errors_test.go
index 1e0730028..223782e23 100644
--- a/common/herrors/errors_test.go
+++ b/common/herrors/errors_test.go
@@ -14,6 +14,7 @@
package herrors
import (
+ "errors"
"fmt"
"testing"
@@ -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)
+
+}
diff --git a/config/commonConfig.go b/config/commonConfig.go
index 2c6497b34..5cf526708 100644
--- a/config/commonConfig.go
+++ b/config/commonConfig.go
@@ -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
diff --git a/resources/resource_transformers/babel/babel.go b/resources/resource_transformers/babel/babel.go
index 5f8fcb00f..2999d73cb 100644
--- a/resources/resource_transformers/babel/babel.go
+++ b/resources/resource_transformers/babel/babel.go
@@ -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
}
@@ -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)
}
diff --git a/resources/resource_transformers/postcss/integration_test.go b/resources/resource_transformers/postcss/integration_test.go
index c920fe17d..74aaa2661 100644
--- a/resources/resource_transformers/postcss/integration_test.go
+++ b/resources/resource_transformers/postcss/integration_test.go
@@ -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() {
diff --git a/resources/resource_transformers/postcss/postcss.go b/resources/resource_transformers/postcss/postcss.go
index 083607246..a65fa3783 100644
--- a/resources/resource_transformers/postcss/postcss.go
+++ b/resources/resource_transformers/postcss/postcss.go
@@ -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
}
@@ -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())
}
diff --git a/resources/transform.go b/resources/transform.go
index 9e5b57625..eb7d8fb0b 100644
--- a/resources/transform.go
+++ b/resources/transform.go
@@ -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