diff --git a/.golangci.yml b/.golangci.yml index 5d40f30f..c19f219e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,6 +15,11 @@ linters-settings: check-type-assertions: true check-blank: true disable-default-exclusions: true + exclude-functions: + - '(*bytes.Buffer).Write' # always returns nil error + - '(*github.com/valyala/bytebufferpool.ByteBuffer).Write' # always returns nil error + - '(*github.com/valyala/bytebufferpool.ByteBuffer).WriteByte' # always returns nil error + - '(*github.com/valyala/bytebufferpool.ByteBuffer).WriteString' # always returns nil error errchkjson: report-no-exported: true @@ -40,7 +45,7 @@ linters-settings: gosec: excludes: - - G104 + - G104 # Provided by errcheck config: global: audit: true @@ -124,6 +129,9 @@ linters-settings: disabled: true - name: unchecked-type-assertion disabled: true # TODO https://github.com/gofiber/fiber/issues/2816 + # Provided by errcheck + - name: unhandled-error + disabled: true stylecheck: checks: diff --git a/ctx.go b/ctx.go index d5d847f9..d58ef263 100644 --- a/ctx.go +++ b/ctx.go @@ -829,11 +829,11 @@ func (c *DefaultCtx) Links(link ...string) { bb := bytebufferpool.Get() for i := range link { if i%2 == 0 { - _ = bb.WriteByte('<') //nolint:errcheck // This will never fail - _, _ = bb.WriteString(link[i]) //nolint:errcheck // This will never fail - _ = bb.WriteByte('>') //nolint:errcheck // This will never fail + bb.WriteByte('<') + bb.WriteString(link[i]) + bb.WriteByte('>') } else { - _, _ = bb.WriteString(`; rel="` + link[i] + `",`) //nolint:errcheck // This will never fail + bb.WriteString(`; rel="` + link[i] + `",`) } } c.setCanonical(HeaderLink, strings.TrimRight(c.app.getString(bb.Bytes()), ",")) @@ -1609,26 +1609,26 @@ func (c *DefaultCtx) String() string { buf := bytebufferpool.Get() // Start with the ID, converting it to a hex string without fmt.Sprintf - buf.WriteByte('#') //nolint:errcheck // It is fine to ignore the error + buf.WriteByte('#') // Convert ID to hexadecimal id := strconv.FormatUint(c.fasthttp.ID(), 16) // Pad with leading zeros to ensure 16 characters for i := 0; i < (16 - len(id)); i++ { - buf.WriteByte('0') //nolint:errcheck // It is fine to ignore the error + buf.WriteByte('0') } - buf.WriteString(id) //nolint:errcheck // It is fine to ignore the error - buf.WriteString(" - ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(id) + buf.WriteString(" - ") // Add local and remote addresses directly - buf.WriteString(c.fasthttp.LocalAddr().String()) //nolint:errcheck // It is fine to ignore the error - buf.WriteString(" <-> ") //nolint:errcheck // It is fine to ignore the error - buf.WriteString(c.fasthttp.RemoteAddr().String()) //nolint:errcheck // It is fine to ignore the error - buf.WriteString(" - ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(c.fasthttp.LocalAddr().String()) + buf.WriteString(" <-> ") + buf.WriteString(c.fasthttp.RemoteAddr().String()) + buf.WriteString(" - ") // Add method and URI - buf.Write(c.fasthttp.Request.Header.Method()) //nolint:errcheck // It is fine to ignore the error - buf.WriteByte(' ') //nolint:errcheck // It is fine to ignore the error - buf.Write(c.fasthttp.URI().FullURI()) //nolint:errcheck // It is fine to ignore the error + buf.Write(c.fasthttp.Request.Header.Method()) + buf.WriteByte(' ') + buf.Write(c.fasthttp.URI().FullURI()) // Allocate string str := buf.String() diff --git a/ctx_test.go b/ctx_test.go index 93b1a1d4..1a7b0bbb 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -3763,7 +3763,7 @@ func Test_Ctx_RenderWithBindVars(t *testing.T) { err = c.Render("./.github/testdata/index.tmpl", Map{}) require.NoError(t, err) buf := bytebufferpool.Get() - _, _ = buf.WriteString("overwrite") //nolint:errcheck // This will never fail + buf.WriteString("overwrite") defer bytebufferpool.Put(buf) require.NoError(t, err) @@ -3786,7 +3786,7 @@ func Test_Ctx_RenderWithOverwrittenBind(t *testing.T) { require.NoError(t, err) buf := bytebufferpool.Get() - _, _ = buf.WriteString("overwrite") //nolint:errcheck // This will never fail + buf.WriteString("overwrite") defer bytebufferpool.Put(buf) require.Equal(t, "

Hello from Fiber!

", string(c.Response().Body())) diff --git a/log/default.go b/log/default.go index 96c751a9..a7a60abd 100644 --- a/log/default.go +++ b/log/default.go @@ -27,8 +27,8 @@ func (l *defaultLogger) privateLog(lv Level, fmtArgs []any) { } level := lv.toString() buf := bytebufferpool.Get() - _, _ = buf.WriteString(level) //nolint:errcheck // It is fine to ignore the error - _, _ = buf.WriteString(fmt.Sprint(fmtArgs...)) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(level) + buf.WriteString(fmt.Sprint(fmtArgs...)) _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error buf.Reset() @@ -46,7 +46,7 @@ func (l *defaultLogger) privateLogf(lv Level, format string, fmtArgs []any) { } level := lv.toString() buf := bytebufferpool.Get() - _, _ = buf.WriteString(level) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(level) if len(fmtArgs) > 0 { _, _ = fmt.Fprintf(buf, format, fmtArgs...) @@ -69,11 +69,11 @@ func (l *defaultLogger) privateLogw(lv Level, format string, keysAndValues []any } level := lv.toString() buf := bytebufferpool.Get() - _, _ = buf.WriteString(level) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(level) // Write format privateLog buffer if format != "" { - _, _ = buf.WriteString(format) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(format) } // Write keys and values privateLog buffer if len(keysAndValues) > 0 { @@ -83,11 +83,11 @@ func (l *defaultLogger) privateLogw(lv Level, format string, keysAndValues []any for i := 0; i < len(keysAndValues); i += 2 { if i > 0 || format != "" { - _ = buf.WriteByte(' ') //nolint:errcheck // It is fine to ignore the error + buf.WriteByte(' ') } - _, _ = buf.WriteString(keysAndValues[i].(string)) //nolint:errcheck // It is fine to ignore the error - _ = buf.WriteByte('=') //nolint:errcheck // It is fine to ignore the error - _, _ = buf.WriteString(utils.ToString(keysAndValues[i+1])) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(keysAndValues[i].(string)) //nolint:forcetypeassert // Keys must be strings + buf.WriteByte('=') + buf.WriteString(utils.ToString(keysAndValues[i+1])) } } diff --git a/log/default_test.go b/log/default_test.go index 3b1eb6f0..9e820b6f 100644 --- a/log/default_test.go +++ b/log/default_test.go @@ -81,14 +81,14 @@ func Test_CtxLogger(t *testing.T) { WithContext(ctx).Debugf("received %s order", work) WithContext(ctx).Infof("starting %s", work) WithContext(ctx).Warnf("%s may fail", work) - WithContext(ctx).Errorf("%s failed", work) + WithContext(ctx).Errorf("%s failed %d", work, 50) WithContext(ctx).Panicf("%s panic", work) require.Equal(t, "[Trace] trace work\n"+ "[Debug] received work order\n"+ "[Info] starting work\n"+ "[Warn] work may fail\n"+ - "[Error] work failed\n"+ + "[Error] work failed 50\n"+ "[Panic] work panic\n", string(w.b)) } diff --git a/middleware/etag/etag.go b/middleware/etag/etag.go index 881e18c5..2a2c0ae1 100644 --- a/middleware/etag/etag.go +++ b/middleware/etag/etag.go @@ -53,14 +53,14 @@ func New(config ...Config) fiber.Handler { // Enable weak tag if cfg.Weak { - _, _ = bb.Write(weakPrefix) //nolint:errcheck // This will never fail + bb.Write(weakPrefix) } - _ = bb.WriteByte('"') //nolint:errcheck // This will never fail + bb.WriteByte('"') bb.B = appendUint(bb.Bytes(), uint32(len(body))) - _ = bb.WriteByte('-') //nolint:errcheck // This will never fail + bb.WriteByte('-') bb.B = appendUint(bb.Bytes(), crc32.Checksum(body, crc32q)) - _ = bb.WriteByte('"') //nolint:errcheck // This will never fail + bb.WriteByte('"') etag := bb.Bytes() diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 49a9202d..22da35bf 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -33,9 +33,9 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { if data.ChainErr != nil { formatErr = colors.Red + " | " + data.ChainErr.Error() + colors.Reset } - _, _ = buf.WriteString( //nolint:errcheck // This will never fail + buf.WriteString( fmt.Sprintf("%s |%s %3d %s| %13v | %15s |%s %-7s %s| %-"+data.ErrPaddingStr+"s %s\n", - data.Timestamp.Load().(string), + data.Timestamp.Load().(string), //nolint:forcetypeassert // Timestamp is always a string statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset, data.Stop.Sub(data.Start), c.IP(), @@ -53,45 +53,45 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { fixedWidth := func(s string, width int, rightAlign bool) { if rightAlign { for i := len(s); i < width; i++ { - _ = buf.WriteByte(' ') //nolint:errcheck // It is fine to ignore the error + buf.WriteByte(' ') } - _, _ = buf.WriteString(s) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(s) } else { - _, _ = buf.WriteString(s) //nolint:errcheck // It is fine to ignore the error + buf.WriteString(s) for i := len(s); i < width; i++ { - _ = buf.WriteByte(' ') //nolint:errcheck // It is fine to ignore the error + buf.WriteByte(' ') } } } // Timestamp - _, _ = buf.WriteString(data.Timestamp.Load().(string)) //nolint:errcheck // It is fine to ignore the error - _, _ = buf.WriteString(" | ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(data.Timestamp.Load().(string)) //nolint:forcetypeassert // Timestamp is always a string + buf.WriteString(" | ") // Status Code with 3 fixed width, right aligned fixedWidth(strconv.Itoa(c.Response().StatusCode()), 3, true) - _, _ = buf.WriteString(" | ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(" | ") // Duration with 13 fixed width, right aligned fixedWidth(data.Stop.Sub(data.Start).String(), 13, true) - _, _ = buf.WriteString(" | ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(" | ") // Client IP with 15 fixed width, right aligned fixedWidth(c.IP(), 15, true) - _, _ = buf.WriteString(" | ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(" | ") // HTTP Method with 7 fixed width, left aligned fixedWidth(c.Method(), 7, false) - _, _ = buf.WriteString(" | ") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(" | ") // Path with dynamic padding for error message, left aligned errPadding, _ := strconv.Atoi(data.ErrPaddingStr) //nolint:errcheck // It is fine to ignore the error fixedWidth(c.Path(), errPadding, false) // Error message - _, _ = buf.WriteString(" ") //nolint:errcheck // It is fine to ignore the error - _, _ = buf.WriteString(formatErr) //nolint:errcheck // It is fine to ignore the error - _, _ = buf.WriteString("\n") //nolint:errcheck // It is fine to ignore the error + buf.WriteString(" ") + buf.WriteString(formatErr) + buf.WriteString("\n") } // Write buffer to output @@ -112,7 +112,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { // Loop over template parts execute dynamic parts and add fixed parts to the buffer for i, logFunc := range data.LogFuncChain { if logFunc == nil { - _, _ = buf.Write(data.TemplateChain[i]) //nolint:errcheck // This will never fail + buf.Write(data.TemplateChain[i]) } else if data.TemplateChain[i] == nil { _, err = logFunc(buf, c, data, "") } else { @@ -125,7 +125,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { // Also write errors to the buffer if err != nil { - _, _ = buf.WriteString(err.Error()) //nolint:errcheck // This will never fail + buf.WriteString(err.Error()) } mu.Lock() diff --git a/middleware/session/store.go b/middleware/session/store.go index ef4ecb44..b176e5f5 100644 --- a/middleware/session/store.go +++ b/middleware/session/store.go @@ -75,7 +75,7 @@ func (s *Store) Get(c fiber.Ctx) (*Session, error) { if raw != nil && err == nil { mux.Lock() defer mux.Unlock() - _, _ = sess.byteBuffer.Write(raw) //nolint:errcheck // This will never fail + sess.byteBuffer.Write(raw) encCache := gob.NewDecoder(sess.byteBuffer) err := encCache.Decode(&sess.data.Data) if err != nil { diff --git a/redirect.go b/redirect.go index bfa8ab77..74b6ad30 100644 --- a/redirect.go +++ b/redirect.go @@ -207,10 +207,10 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error { // flash messages for i, message := range r.messages { - _, _ = messageText.WriteString(message) //nolint:errcheck // Always return nil + messageText.WriteString(message) // when there are more messages or oldInput -> add a comma if len(r.messages)-1 != i || (len(r.messages)-1 == i && len(r.oldInput) > 0) { - _, _ = messageText.WriteString(CookieDataSeparator) //nolint:errcheck // Always return nil + messageText.WriteString(CookieDataSeparator) } } r.messages = r.messages[:0] @@ -218,9 +218,9 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error { // old input data i := 1 for k, v := range r.oldInput { - _, _ = messageText.WriteString(OldInputDataPrefix + k + CookieDataAssigner + v) //nolint:errcheck // Always return nil + messageText.WriteString(OldInputDataPrefix + k + CookieDataAssigner + v) if len(r.oldInput) != i { - _, _ = messageText.WriteString(CookieDataSeparator) //nolint:errcheck // Always return nil + messageText.WriteString(CookieDataSeparator) } i++ } @@ -239,10 +239,10 @@ func (r *Redirect) Route(name string, config ...RedirectConfig) error { i := 1 for k, v := range cfg.Queries { - _, _ = queryText.WriteString(k + "=" + v) //nolint:errcheck // Always return nil + queryText.WriteString(k + "=" + v) if i != len(cfg.Queries) { - _, _ = queryText.WriteString("&") //nolint:errcheck // Always return nil + queryText.WriteString("&") } i++ } diff --git a/redirect_test.go b/redirect_test.go index f3b1e7ca..33241e3e 100644 --- a/redirect_test.go +++ b/redirect_test.go @@ -341,14 +341,17 @@ func Benchmark_Redirect_Route(b *testing.B) { b.ReportAllocs() b.ResetTimer() + var err error + for n := 0; n < b.N; n++ { - c.Redirect().Route("user", RedirectConfig{ //nolint:errcheck,revive // we don't need to handle error here + err = c.Redirect().Route("user", RedirectConfig{ Params: Map{ "name": "fiber", }, }) } + require.NoError(b, err) require.Equal(b, 302, c.Response().StatusCode()) require.Equal(b, "/user/fiber", string(c.Response().Header.Peek(HeaderLocation))) } @@ -365,8 +368,10 @@ func Benchmark_Redirect_Route_WithQueries(b *testing.B) { b.ReportAllocs() b.ResetTimer() + var err error + for n := 0; n < b.N; n++ { - c.Redirect().Route("user", RedirectConfig{ //nolint:errcheck,revive // we don't need to handle error here + err = c.Redirect().Route("user", RedirectConfig{ Params: Map{ "name": "fiber", }, @@ -374,6 +379,7 @@ func Benchmark_Redirect_Route_WithQueries(b *testing.B) { }) } + require.NoError(b, err) require.Equal(b, 302, c.Response().StatusCode()) // analysis of query parameters with url parsing, since a map pass is always randomly ordered location, err := url.Parse(string(c.Response().Header.Peek(HeaderLocation))) @@ -394,10 +400,13 @@ func Benchmark_Redirect_Route_WithFlashMessages(b *testing.B) { b.ReportAllocs() b.ResetTimer() + var err error + for n := 0; n < b.N; n++ { - c.Redirect().With("success", "1").With("message", "test").Route("user") //nolint:errcheck,revive // we don't need to handle error here + err = c.Redirect().With("success", "1").With("message", "test").Route("user") } + require.NoError(b, err) require.Equal(b, 302, c.Response().StatusCode()) require.Equal(b, "/user", string(c.Response().Header.Peek(HeaderLocation)))