Repository: beatlabs/patron
Pull request #692 (2024-05-04 14:56:20)

Remove errors package
<!--
Thanks for taking precious time for making a PR.

Before creating a pull request, please make sure:
- Your PR solves one problem for which an issue exist and a solution has been discussed
- You have read the guide for contributing
  - See https://github.com/beatlabs/patron/blob/master/README.md#how-to-contribute
- You signed all your commits (otherwise we won't be able to merge the PR)
  - See https://github.com/beatlabs/patron/blob/master/SIGNYOURWORK.md
- You added unit tests for the new functionality
- You mention in the PR description which issue it is addressing, e.g. "Resolves #123"
-->

## Which problem is this PR solving?

Remove errors package.

## Short description of the changes

Remove errors package and use errors.Join from std.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/beatlabs/patron/pull/692?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) Report
Attention: Patch coverage is `66.66667%` with `7 lines` in your changes are missing coverage. Please review.
> Project coverage is 79.44%. Comparing base [(`51835d0`)](https://app.codecov.io/gh/beatlabs/patron/commit/51835d058106d5da2fb217331a6180943a873d67?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) to head [(`8c61a9f`)](https://app.codecov.io/gh/beatlabs/patron/pull/692?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs).

| [Files](https://app.codecov.io/gh/beatlabs/patron/pull/692?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) | Patch % | Lines |
|---|---|---|
| [client/amqp/amqp.go](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&filepath=client%2Famqp%2Famqp.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs#diff-Y2xpZW50L2FtcXAvYW1xcC5nbw==) | 0.00% | [2 Missing :warning: ](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) |
| [component/amqp/component.go](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&filepath=component%2Famqp%2Fcomponent.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs#diff-Y29tcG9uZW50L2FtcXAvY29tcG9uZW50Lmdv) | 33.33% | [2 Missing :warning: ](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) |
| [client/kafka/async\_producer.go](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&filepath=client%2Fkafka%2Fasync_producer.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs#diff-Y2xpZW50L2thZmthL2FzeW5jX3Byb2R1Y2VyLmdv) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) |
| [client/kafka/sync\_producer.go](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&filepath=client%2Fkafka%2Fsync_producer.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs#diff-Y2xpZW50L2thZmthL3N5bmNfcHJvZHVjZXIuZ28=) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) |
| [component/http/route\_option.go](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&filepath=component%2Fhttp%2Froute_option.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs#diff-Y29tcG9uZW50L2h0dHAvcm91dGVfb3B0aW9uLmdv) | 50.00% | [1 Missing :warning: ](https://app.codecov.io/gh/beatlabs/patron/pull/692?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #692      +/-   ##
==========================================
- Coverage   79.56%   79.44%   -0.13%     
==========================================
  Files          69       68       -1     
  Lines        4082     4067      -15     
==========================================
- Hits         3248     3231      -17     
- Misses        684      685       +1     
- Partials      150      151       +1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/beatlabs/patron/pull/692?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=beatlabs).


Patch:
diff --git a/client/amqp/amqp.go b/client/amqp/amqp.go
index 0f8d486af..06e900495 100644
--- a/client/amqp/amqp.go
+++ b/client/amqp/amqp.go
@@ -10,7 +10,6 @@ import (
 	"time"
 
 	"github.com/beatlabs/patron/correlation"
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/log"
 	"github.com/beatlabs/patron/trace"
 	"github.com/opentracing/opentracing-go"
@@ -74,7 +73,7 @@ func New(url string, oo ...OptionFunc) (*Publisher, error) {
 
 	ch, err := conn.Channel()
 	if err != nil {
-		return nil, patronerrors.Aggregate(fmt.Errorf("failed to open channel: %w", err), conn.Close())
+		return nil, errors.Join(fmt.Errorf("failed to open channel: %w", err), conn.Close())
 	}
 
 	pub.connection = conn
@@ -116,7 +115,7 @@ func injectTraceHeaders(ctx context.Context, exchange string, msg *amqp.Publishi
 
 // Close the channel and connection.
 func (tc *Publisher) Close() error {
-	return patronerrors.Aggregate(tc.channel.Close(), tc.connection.Close())
+	return errors.Join(tc.channel.Close(), tc.connection.Close())
 }
 
 type amqpHeadersCarrier map[string]interface{}
diff --git a/client/kafka/async_producer.go b/client/kafka/async_producer.go
index 694400ab4..ff419a3d1 100644
--- a/client/kafka/async_producer.go
+++ b/client/kafka/async_producer.go
@@ -3,10 +3,10 @@ package kafka
 
 import (
 	"context"
+	"errors"
 	"fmt"
 
 	"github.com/IBM/sarama"
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/trace"
 	"github.com/opentracing/opentracing-go"
 	"github.com/opentracing/opentracing-go/ext"
@@ -51,7 +51,7 @@ func (ap *AsyncProducer) propagateError(chErr chan<- error) {
 // scope, as it may otherwise leak memory.
 func (ap *AsyncProducer) Close() error {
 	if err := ap.asyncProd.Close(); err != nil {
-		return patronerrors.Aggregate(fmt.Errorf("failed to close async producer client: %w", err), ap.prodClient.Close())
+		return errors.Join(fmt.Errorf("failed to close async producer client: %w", err), ap.prodClient.Close())
 	}
 	if err := ap.prodClient.Close(); err != nil {
 		return fmt.Errorf("failed to close async producer: %w", err)
diff --git a/client/kafka/kafka.go b/client/kafka/kafka.go
index d319b2b49..6212a0c18 100644
--- a/client/kafka/kafka.go
+++ b/client/kafka/kafka.go
@@ -8,7 +8,6 @@ import (
 
 	"github.com/IBM/sarama"
 	"github.com/beatlabs/patron/correlation"
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/internal/validation"
 	"github.com/opentracing/opentracing-go"
 	"github.com/prometheus/client_golang/prometheus"
@@ -111,7 +110,7 @@ func DefaultProducerSaramaConfig(name string, idempotent bool) (*sarama.Config,
 // Create a new synchronous producer.
 func (b *Builder) Create() (*SyncProducer, error) {
 	if len(b.errs) > 0 {
-		return nil, patronerrors.Aggregate(b.errs...)
+		return nil, errors.Join(b.errs...)
 	}
 
 	// required for any SyncProducer; 'Errors' is already true by default for both async/sync producers
@@ -136,7 +135,7 @@ func (b *Builder) Create() (*SyncProducer, error) {
 // CreateAsync a new asynchronous producer.
 func (b Builder) CreateAsync() (*AsyncProducer, <-chan error, error) {
 	if len(b.errs) > 0 {
-		return nil, nil, patronerrors.Aggregate(b.errs...)
+		return nil, nil, errors.Join(b.errs...)
 	}
 
 	ap := &AsyncProducer{
diff --git a/client/kafka/sync_producer.go b/client/kafka/sync_producer.go
index 39aa81e16..05cf4c630 100644
--- a/client/kafka/sync_producer.go
+++ b/client/kafka/sync_producer.go
@@ -6,7 +6,6 @@ import (
 	"fmt"
 
 	"github.com/IBM/sarama"
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/trace"
 	"github.com/opentracing/opentracing-go"
 	"github.com/opentracing/opentracing-go/ext"
@@ -87,7 +86,7 @@ func (p *SyncProducer) SendBatch(ctx context.Context, messages []*sarama.Produce
 // scope, as it may otherwise leak memory.
 func (p *SyncProducer) Close() error {
 	if err := p.syncProd.Close(); err != nil {
-		return patronerrors.Aggregate(fmt.Errorf("failed to close sync producer client: %w", err), p.prodClient.Close())
+		return errors.Join(fmt.Errorf("failed to close sync producer client: %w", err), p.prodClient.Close())
 	}
 	if err := p.prodClient.Close(); err != nil {
 		return fmt.Errorf("failed to close sync producer: %w", err)
diff --git a/component/amqp/component.go b/component/amqp/component.go
index ea52fd560..0ad9ecdf5 100644
--- a/component/amqp/component.go
+++ b/component/amqp/component.go
@@ -10,7 +10,6 @@ import (
 	"time"
 
 	"github.com/beatlabs/patron/correlation"
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/log"
 	"github.com/beatlabs/patron/trace"
 	"github.com/google/uuid"
@@ -259,7 +258,7 @@ func (s *subscription) close() error {
 		ee = append(ee, s.conn.Close())
 	}
 	s.closed = true
-	return patronerrors.Aggregate(ee...)
+	return errors.Join(ee...)
 }
 
 func (c *Component) subscribe() (subscription, error) {
@@ -271,7 +270,7 @@ func (c *Component) subscribe() (subscription, error) {
 
 	ch, err := conn.Channel()
 	if err != nil {
-		return subscription{}, patronerrors.Aggregate(conn.Close(), fmt.Errorf("failed get channel: %w", err))
+		return subscription{}, errors.Join(conn.Close(), fmt.Errorf("failed get channel: %w", err))
 	}
 	sub.channel = ch
 
@@ -280,7 +279,7 @@ func (c *Component) subscribe() (subscription, error) {
 
 	deliveries, err := ch.Consume(c.queueCfg.queue, tag, false, false, false, false, nil)
 	if err != nil {
-		return subscription{}, patronerrors.Aggregate(ch.Close(), conn.Close(), fmt.Errorf("failed initialize amqp consumer: %w", err))
+		return subscription{}, errors.Join(ch.Close(), conn.Close(), fmt.Errorf("failed initialize amqp consumer: %w", err))
 	}
 	sub.deliveries = deliveries
 
diff --git a/component/amqp/message.go b/component/amqp/message.go
index ea71b9f3a..9764d1052 100644
--- a/component/amqp/message.go
+++ b/component/amqp/message.go
@@ -2,8 +2,8 @@ package amqp
 
 import (
 	"context"
+	"errors"
 
-	patronerrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/trace"
 	"github.com/opentracing/opentracing-go"
 	"github.com/streadway/amqp"
@@ -87,33 +87,33 @@ type batch struct {
 }
 
 func (b *batch) ACK() ([]Message, error) {
-	var errors []error
+	var errs []error
 	var failed []Message
 
 	for _, msg := range b.messages {
 		err := msg.ACK()
 		if err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 			failed = append(failed, msg)
 		}
 	}
 
-	return failed, patronerrors.Aggregate(errors...)
+	return failed, errors.Join(errs...)
 }
 
 func (b *batch) NACK() ([]Message, error) {
-	var errors []error
+	var errs []error
 	var failed []Message
 
 	for _, msg := range b.messages {
 		err := msg.NACK()
 		if err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 			failed = append(failed, msg)
 		}
 	}
 
-	return failed, patronerrors.Aggregate(errors...)
+	return failed, errors.Join(errs...)
 }
 
 func (b *batch) Messages() []Message {
diff --git a/component/http/route.go b/component/http/route.go
index 33461c800..d6ec0f152 100644
--- a/component/http/route.go
+++ b/component/http/route.go
@@ -5,7 +5,6 @@ import (
 	"net/http"
 
 	patronhttp "github.com/beatlabs/patron/component/http/middleware"
-	patronerrors "github.com/beatlabs/patron/errors"
 )
 
 // RouteOptionFunc definition for configuring the route in a functional way.
@@ -80,5 +79,5 @@ func (r *Routes) Append(route *Route, err error) {
 
 // Result of the route aggregation.
 func (r *Routes) Result() ([]*Route, error) {
-	return r.routes, patronerrors.Aggregate(r.ee...)
+	return r.routes, errors.Join(r.ee...)
 }
diff --git a/component/http/route_option.go b/component/http/route_option.go
index a23c7fb93..fc545bc73 100644
--- a/component/http/route_option.go
+++ b/component/http/route_option.go
@@ -8,7 +8,6 @@ import (
 	"github.com/beatlabs/patron/component/http/auth"
 	httpcache "github.com/beatlabs/patron/component/http/cache"
 	patronhttp "github.com/beatlabs/patron/component/http/middleware"
-	errs "github.com/beatlabs/patron/errors"
 	"golang.org/x/time/rate"
 )
 
@@ -62,11 +61,11 @@ func WithCache(cache cache.TTLCache, ageBounds httpcache.Age) RouteOptionFunc {
 		}
 		rc, ee := httpcache.NewRouteCache(cache, ageBounds)
 		if len(ee) != 0 {
-			return errs.Aggregate(ee...)
+			return errors.Join(ee...)
 		}
 		m, err := patronhttp.NewCaching(rc)
 		if err != nil {
-			return errs.Aggregate(err)
+			return errors.Join(err)
 		}
 		r.middlewares = append(r.middlewares, m)
 		return nil
diff --git a/component/kafka/component.go b/component/kafka/component.go
index 84621d9cb..346813064 100644
--- a/component/kafka/component.go
+++ b/component/kafka/component.go
@@ -11,7 +11,6 @@ import (
 
 	"github.com/IBM/sarama"
 	"github.com/beatlabs/patron/correlation"
-	patronErrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/internal/validation"
 	"github.com/beatlabs/patron/log"
 	"github.com/beatlabs/patron/trace"
@@ -126,7 +125,7 @@ func New(name, group string, brokers, topics []string, proc BatchProcessorFunc,
 	}
 
 	if len(errs) > 0 {
-		return nil, patronErrors.Aggregate(errs...)
+		return nil, errors.Join(errs...)
 	}
 
 	cmp := &Component{
diff --git a/errors/aggregate.go b/errors/aggregate.go
deleted file mode 100644
index b962d42c8..000000000
--- a/errors/aggregate.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Package errors provides useful error handling implementations.
-package errors
-
-import (
-	"strings"
-)
-
-type aggregate []error
-
-// Error returns the string representation of the aggregated errors.
-// Internally it uses a string builder in order to efficiently merge errors into one.
-func (a aggregate) Error() string {
-	b := strings.Builder{}
-	for _, err := range a {
-		b.WriteString(err.Error())
-		b.WriteRune('\n')
-	}
-	return b.String()
-}
-
-// Aggregate errors into one error.
-// If the provided errors contain a nil it will be skipped.
-func Aggregate(ee ...error) error {
-	agr := make(aggregate, 0, len(ee))
-	for _, e := range ee {
-		if e == nil {
-			continue
-		}
-		agr = append(agr, e)
-	}
-	if len(agr) == 0 {
-		return nil
-	}
-	return agr
-}
diff --git a/service.go b/service.go
index afbfd1c27..5557367a2 100644
--- a/service.go
+++ b/service.go
@@ -12,7 +12,6 @@ import (
 	"sync"
 	"syscall"
 
-	patronErrors "github.com/beatlabs/patron/errors"
 	"github.com/beatlabs/patron/log"
 	"github.com/beatlabs/patron/trace"
 	"github.com/uber/jaeger-client-go"
@@ -75,7 +74,7 @@ func New(name, version string, options ...OptionFunc) (*Service, error) {
 	}
 
 	if len(optionErrors) > 0 {
-		return nil, patronErrors.Aggregate(optionErrors...)
+		return nil, errors.Join(optionErrors...)
 	}
 
 	setupLogging(s.logConfig)
@@ -117,7 +116,7 @@ func (s *Service) Run(ctx context.Context, components ...Component) error {
 	for err := range chErr {
 		ee = append(ee, err)
 	}
-	return patronErrors.Aggregate(ee...)
+	return errors.Join(ee...)
 }
 
 func (s *Service) setupOSSignal() {


Test patch:
diff --git a/client/kafka/kafka_test.go b/client/kafka/kafka_test.go
index a2cc74508..3db939333 100644
--- a/client/kafka/kafka_test.go
+++ b/client/kafka/kafka_test.go
@@ -26,8 +26,8 @@ func TestBuilder_Create(t *testing.T) {
 		args        args
 		expectedErr string
 	}{
-		"missing brokers": {args: args{brokers: nil, cfg: sarama.NewConfig()}, expectedErr: "brokers are empty or have an empty value\n"},
-		"missing config":  {args: args{brokers: []string{"123"}, cfg: nil}, expectedErr: "no Sarama configuration specified\n"},
+		"missing brokers": {args: args{brokers: nil, cfg: sarama.NewConfig()}, expectedErr: "brokers are empty or have an empty value"},
+		"missing config":  {args: args{brokers: []string{"123"}, cfg: nil}, expectedErr: "no Sarama configuration specified"},
 	}
 	for name, tt := range tests {
 		tt := tt
@@ -51,8 +51,8 @@ func TestBuilder_CreateAsync(t *testing.T) {
 		args        args
 		expectedErr string
 	}{
-		"missing brokers": {args: args{brokers: nil, cfg: sarama.NewConfig()}, expectedErr: "brokers are empty or have an empty value\n"},
-		"missing config":  {args: args{brokers: []string{"123"}, cfg: nil}, expectedErr: "no Sarama configuration specified\n"},
+		"missing brokers": {args: args{brokers: nil, cfg: sarama.NewConfig()}, expectedErr: "brokers are empty or have an empty value"},
+		"missing config":  {args: args{brokers: []string{"123"}, cfg: nil}, expectedErr: "no Sarama configuration specified"},
 	}
 	for name, tt := range tests {
 		tt := tt
diff --git a/component/amqp/message_test.go b/component/amqp/message_test.go
index a6f60ab0d..a340f7630 100644
--- a/component/amqp/message_test.go
+++ b/component/amqp/message_test.go
@@ -169,7 +169,7 @@ func Test_batch_ACK(t *testing.T) {
 	btc := batch{messages: []Message{msg1, msg2}}
 
 	got, err := btc.ACK()
-	assert.EqualError(t, err, "ERROR\n")
+	assert.EqualError(t, err, "ERROR")
 	assert.Len(t, got, 1)
 	assert.Equal(t, msg2, got[0])
 }
@@ -184,7 +184,7 @@ func Test_batch_NACK(t *testing.T) {
 	btc := batch{messages: []Message{msg1, msg2}}
 
 	got, err := btc.NACK()
-	assert.EqualError(t, err, "ERROR\n")
+	assert.EqualError(t, err, "ERROR")
 	assert.Len(t, got, 1)
 	assert.Equal(t, msg2, got[0])
 }
diff --git a/component/http/route_option_test.go b/component/http/route_option_test.go
index 5729c9c07..78f16766d 100644
--- a/component/http/route_option_test.go
+++ b/component/http/route_option_test.go
@@ -136,7 +136,7 @@ func TestCache(t *testing.T) {
 		"fail with args": {
 			fields:      fields{path: "GET /api"},
 			args:        args{cache: nil, ageBounds: httpcache.Age{}},
-			expectedErr: "route cache is nil\n",
+			expectedErr: "route cache is nil",
 		},
 	}
 	for name, tt := range tests {
diff --git a/component/http/route_test.go b/component/http/route_test.go
index 9a4a881fd..42045831c 100644
--- a/component/http/route_test.go
+++ b/component/http/route_test.go
@@ -81,8 +81,8 @@ func TestRoutes_Append(t *testing.T) {
 		expectedErr string
 	}{
 		"success":      {args: args{route: &Route{}, err: nil}},
-		"error exist":  {args: args{route: &Route{}, err: errors.New("TEST")}, expectedErr: "TEST\n"},
-		"route is nil": {args: args{route: nil, err: nil}, expectedErr: "route is nil\n"},
+		"error exist":  {args: args{route: &Route{}, err: errors.New("TEST")}, expectedErr: "TEST"},
+		"route is nil": {args: args{route: nil, err: nil}, expectedErr: "route is nil"},
 	}
 	for name, tt := range tests {
 		tt := tt
diff --git a/errors/aggregate_test.go b/errors/aggregate_test.go
deleted file mode 100644
index a57bf9b2b..000000000
--- a/errors/aggregate_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package errors
-
-import (
-	"errors"
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestAggregate(t *testing.T) {
-	a := Aggregate(errors.New("error 1"), errors.New("error 2"), nil, errors.New("error 3"))
-	assert.Len(t, a, 3)
-	assert.Equal(t, "error 1\nerror 2\nerror 3\n", a.Error())
-}
-
-func TestAggregate_ReturnsNil(t *testing.T) {
-	assert.Nil(t, Aggregate(nil, nil, nil))
-}
-
-var err error
-
-func BenchmarkAggregate(b *testing.B) {
-	err1 := errors.New("error 1")
-	err2 := errors.New("error 2")
-	err3 := fmt.Errorf("error inner: %w", errors.New("error 3"))
-
-	var innerErr error
-
-	for n := 0; n < b.N; n++ {
-		innerErr = Aggregate(err1, nil, err2, nil, err3, nil)
-	}
-	err = innerErr
-}
-
-func ExampleAggregate() {
-	err1 := errors.New("error 1")
-	err2 := errors.New("error 2")
-	err3 := fmt.Errorf("error inner: %w", errors.New("error 3"))
-
-	err := Aggregate(err1, nil, err2, nil, err3)
-
-	fmt.Println(err)
-	// Output: error 1
-	// error 2
-	// error inner: error 3
-}
diff --git a/service_test.go b/service_test.go
index 8ba91e4b0..daf9836eb 100644
--- a/service_test.go
+++ b/service_test.go
@@ -12,7 +12,7 @@ import (
 )
 
 func TestNew(t *testing.T) {
-	httpBuilderAllErrors := "attributes are empty\nprovided WithSIGHUP handler was nil\n"
+	httpBuilderAllErrors := "attributes are empty\nprovided WithSIGHUP handler was nil"
 
 	tests := map[string]struct {
 		name              string