{"record":{"id":"2173f5f98480a35a","repo":"gofr-dev/gofr","slug":"errors-wrap-e-err-e-message-error","errorCode":null,"errorMessage":"errors.Wrap(e.Err, e.Message).Error()","messagePattern":"errors\\.Wrap\\(e\\.Err, e\\.Message\\)\\.Error\\(\\)","errorType":"exception","errorClass":"ErrorDB","httpStatus":null,"severity":"warning","filePath":"pkg/gofr/datasource/errors.go","lineNumber":22,"sourceCode":"\t\"net/http\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// ErrorDB represents an error specific to database operations.\ntype ErrorDB struct {\n\tErr     error\n\tMessage string\n}\n\nfunc (e ErrorDB) Error() string {\n\tswitch {\n\tcase e.Message == \"\":\n\t\treturn e.Err.Error()\n\tcase e.Err == nil:\n\t\treturn e.Message\n\tdefault:\n\t\treturn errors.Wrap(e.Err, e.Message).Error()\n\t}\n}\n\n// WithStack adds a stack trace to the Error.\nfunc (e ErrorDB) WithStack() ErrorDB {\n\te.Err = errors.WithStack(e.Err)\n\treturn e\n}\n\nfunc (ErrorDB) StatusCode() int {\n\treturn http.StatusInternalServerError\n}\n\n// ErrorRecordNotFound represents the scenario where no records are found in the DB for the given ID.\ntype ErrorRecordNotFound ErrorDB\n\n// StatusCode implementation on the ErrorRecordNotFound is an aberration\n// since the errors in datasource package should not have anything to do with HTTP status codes.","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/errors.go#L4-L40","documentation":"ErrorDB is gofr's structured database error type holding an underlying Err and a human-readable Message. Its Error() method switches on which fields are populated: empty Message returns just the inner error's text, nil Err returns just the message, and when both are set it delegates to github.com/pkg/errors.Wrap(e.Err, e.Message).Error(), producing \"Message: inner error text\". This is the string rendering path, hit whenever any ErrorDB is printed, logged, or compared.","triggerScenarios":"Rendering any ErrorDB where both Err and Message are non-empty — e.g. a datasource operation failing and being wrapped with context like \"failed to fetch user\" plus the driver error. The error itself is thrown by whatever populated the ErrorDB; this line only formats it.","commonSituations":"Logging DB query failures in service handlers; comparing err.Error() output in tests expecting a specific message format; wrapping SQL driver errors with business context; cascading errors where each layer adds its own message prefix.","solutions":["Read the full formatted string — the prefix is the library's contextual Message and the suffix is the original driver error.","Use errors.Is/As or unwrap (ErrorDB stores Err) to test for specific driver errors instead of string matching.","If the message is unhelpfully empty or duplicated, check how the ErrorDB was constructed upstream (EmptyMessage vs nil Err branches).","Call WithStack() on the ErrorDB when you need a stack trace captured for debugging."],"exampleFix":"// before\nif err != nil {\n    if strings.Contains(err.Error(), \"duplicate key\") { ... }\n}\n// after\nvar errDB gofrErrorDB\nif errors.As(err, &errDB) && errors.Is(errDB.Err, sql.ErrNoRows) {\n    // handle not-found precisely\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asErrorDB(err error) (msg string, cause error, ok bool) {\n    var edb datasource.ErrorDB\n    if errors.As(err, &edb) {\n        return edb.Error(), edb.Err, true\n    }\n    return \"\", nil, false\n}","tryCatchPattern":"if err != nil {\n    if cause := errors.Unwrap(err); cause != nil {\n        logger.Errorf(\"db op failed: %v (cause: %v)\", err, cause)\n    } else {\n        logger.Errorf(\"db op failed: %v\", err)\n    }\n    return err\n}","preventionTips":["Match on unwrapped causes with errors.Is/errors.As instead of string comparisons on Error().","Call WithStack() when capturing ErrorDB for diagnostics.","When wrapping, provide a meaningful Message so logs are actionable.","Test both wrap branches (Message+Err, Message only, Err only) in unit tests."],"tags":["database","error-wrapping","golang","error-formatting"],"backgroundTag":"db-error-wrapping","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}