Robust Error Tracking and Reporting in Go
Error handling is crucial for building reliable Go applications. This challenge focuses on implementing a system that not only handles errors gracefully but also tracks and reports them in a structured manner, allowing for easier debugging and monitoring. You'll build a simple error tracking service that logs errors with context and potentially sends them to a centralized reporting system (simulated here).
Problem Description
You are tasked with creating a Go package named errtrack that provides a mechanism for tracking and reporting errors within an application. The package should include:
-
TrackError(err error, context string)Function: This function takes an error and a context string as input. It should log the error and context to standard error (for demonstration purposes – in a real application, this would be a more sophisticated logging system). It should also return a modified error that includes the context. -
ReportError(err error)Function: This function takes an error as input. It should extract the context from the error (if present – see point 1) and simulate sending the error and context to a centralized error reporting system (again, for demonstration, just print to standard error). If no context is present, it should simply print the error. -
Contextual Error Type: Define a custom error type
ContextualErrorthat embeds the standarderrorinterface and adds aContextfield (string). This will allow you to attach context information to errors. -
Error Wrapping: The
TrackErrorfunction should wrap the original error with theContextualErrortype, ensuring that the context is preserved throughout the error chain.
Expected Behavior:
TrackErrorshould log the error and context to standard error.TrackErrorshould return a new error of typeContextualErrorcontaining the original error and the provided context.ReportErrorshould extract and log the context (if available) along with the error to standard error.- If an error is passed to
ReportErrorthat is not aContextualError, it should simply log the error itself.
Edge Cases to Consider:
- What happens if
TrackErroris called with anilerror? (Should handle gracefully, likely by logging a message and returningnil). - What happens if
ReportErroris called with anilerror? (Should handle gracefully, likely by doing nothing). - How to handle errors that are already wrapped (e.g., using
fmt.Errorfwith%w)? TheTrackErrorfunction should be able to handle these and still extract the context.
Examples
Example 1:
Input: err := errors.New("database connection failed"); context := "User Authentication"; err = errtrack.TrackError(err, context)
Output: (printed to stderr) "Error: database connection failed, Context: User Authentication"
Explanation: The TrackError function logs the error and context, and returns a ContextualError.
Example 2:
Input: errtrack.ReportError(err) // where err is the result of Example 1
Output: (printed to stderr) "Error: database connection failed, Context: User Authentication"
Explanation: The ReportError function extracts and logs the context from the ContextualError.
Example 3:
Input: err := errors.New("file not found"); errtrack.ReportError(err)
Output: (printed to stderr) "Error: file not found"
Explanation: The ReportError function logs the error because it's not a ContextualError.
Constraints
- The
TrackErrorfunction must not modify the original error object passed to it. It must create a new error. - The
ReportErrorfunction should handle bothContextualErrorand standarderrortypes gracefully. - The solution must be implemented in Go.
- The code should be well-documented and easy to understand.
- The solution should be efficient; avoid unnecessary allocations or computations.
Notes
- Consider using Go's error wrapping capabilities (
fmt.Errorfwith%w) to preserve the original error while adding context. - Think about how to handle errors that are already wrapped. You might need to unwrap the error to access the underlying error and its context.
- This is a simplified simulation of error tracking. In a real-world scenario, you would likely integrate with a dedicated error tracking service (e.g., Sentry, Rollbar). The logging to standard error is just a placeholder.
- Focus on the core functionality of tracking and reporting errors with context. Don't worry about complex features like error aggregation or deduplication.