TestSetErrWithWrappedError tests that when a hook wraps an error and sets it via cmd.SetErr(), the underlying typed error can still be detected
(t *testing.T)
| 359 | // TestSetErrWithWrappedError tests that when a hook wraps an error and sets it |
| 360 | // via cmd.SetErr(), the underlying typed error can still be detected |
| 361 | func TestSetErrWithWrappedError(t *testing.T) { |
| 362 | testCtx := context.Background() |
| 363 | |
| 364 | // Test with a simulated LOADING error |
| 365 | // We test the mechanism directly without needing a real Redis server |
| 366 | cmd := redis.NewStatusCmd(testCtx, "GET", "key") |
| 367 | loadingErr := proto.ParseErrorReply([]byte("-LOADING Redis is loading the dataset in memory")) |
| 368 | wrappedLoadingErr := fmt.Errorf("hook wrapper: %w", loadingErr) |
| 369 | cmd.SetErr(wrappedLoadingErr) |
| 370 | |
| 371 | // Verify we can still detect the LOADING error through the wrapper |
| 372 | if !redis.IsLoadingError(cmd.Err()) { |
| 373 | t.Errorf("IsLoadingError failed to detect wrapped error set via SetErr: %v", cmd.Err()) |
| 374 | } |
| 375 | |
| 376 | // Test with MOVED error |
| 377 | cmd2 := redis.NewStatusCmd(testCtx, "GET", "key") |
| 378 | movedErr := proto.ParseErrorReply([]byte("-MOVED 3999 127.0.0.1:6381")) |
| 379 | wrappedMovedErr := fmt.Errorf("hook wrapper: %w", movedErr) |
| 380 | cmd2.SetErr(wrappedMovedErr) |
| 381 | |
| 382 | // Verify we can still detect and extract address from MOVED error |
| 383 | addr, ok := redis.IsMovedError(cmd2.Err()) |
| 384 | if !ok { |
| 385 | t.Errorf("IsMovedError failed to detect wrapped error set via SetErr: %v", cmd2.Err()) |
| 386 | } |
| 387 | if addr != "127.0.0.1:6381" { |
| 388 | t.Errorf("Address extraction failed: got %q, want %q", addr, "127.0.0.1:6381") |
| 389 | } |
| 390 | |
| 391 | // Test with READONLY error |
| 392 | cmd3 := redis.NewStatusCmd(testCtx, "SET", "key", "value") |
| 393 | readonlyErr := proto.ParseErrorReply([]byte("-READONLY You can't write against a read only replica")) |
| 394 | wrappedReadonlyErr := fmt.Errorf("custom error wrapper: %w", readonlyErr) |
| 395 | cmd3.SetErr(wrappedReadonlyErr) |
| 396 | |
| 397 | // Verify we can still detect the READONLY error through the wrapper |
| 398 | if !redis.IsReadOnlyError(cmd3.Err()) { |
| 399 | t.Errorf("IsReadOnlyError failed to detect wrapped error set via SetErr: %v", cmd3.Err()) |
| 400 | } |
| 401 | |
| 402 | // Verify the error message contains both the wrapper and original error |
| 403 | errMsg := cmd3.Err().Error() |
| 404 | if !contains(errMsg, "custom error wrapper") { |
| 405 | t.Errorf("Error message missing wrapper context: %v", errMsg) |
| 406 | } |
| 407 | if !contains(errMsg, "READONLY") { |
| 408 | t.Errorf("Error message missing original error: %v", errMsg) |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | // AppError is a custom error type for testing |
| 413 | type AppError struct { |
nothing calls this directly
no test coverage detected
searching dependent graphs…