Skip to content

GH-3346 Fix RedisPipelineException double-wrapping in LettuceConnection.closePipeline().#3347

Open
JEONGJAEIK wants to merge 1 commit intospring-projects:mainfrom
JEONGJAEIK:fix/close-pipeline-exception-wrapping
Open

GH-3346 Fix RedisPipelineException double-wrapping in LettuceConnection.closePipeline().#3347
JEONGJAEIK wants to merge 1 commit intospring-projects:mainfrom
JEONGJAEIK:fix/close-pipeline-exception-wrapping

Conversation

@JEONGJAEIK
Copy link
Copy Markdown

@JEONGJAEIK JEONGJAEIK commented Apr 11, 2026

Bug Description

LettuceConnection.closePipeline() wraps all exceptions in a generic RedisPipelineException with the misleading message "Pipeline contained one or more invalid commands", even when the actual cause is a timeout or a failed Redis command.

Root Cause

The try-catch block in closePipeline() is too broad. Both intentional RedisPipelineException throws (lines 646 and 653) are caught by the same
catch (Exception ex) block, causing them to be wrapped again in a new RedisPipelineException.

// Both of these throws are caught below...
throw new RedisPipelineException(problem, results);                          // line 646
throw new RedisPipelineException(new QueryTimeoutException("...timed out")); // line 653

} catch (Exception ex) {
    // ...and re-wrapped here with a misleading message
    throw new RedisPipelineException(ex);
}

Impact

  • A timeout (awaitAll returns false) surfaces as:
    RedisPipelineException("Pipeline contained one or more invalid commands", cause=RedisPipelineException(cause=QueryTimeoutException)) instead of: RedisPipelineException(cause=QueryTimeoutException)

  • A failed command surfaces with the same misleading message and an extra layer of wrapping, making it impossible to distinguish a timeout from an actual invalid command via getCause().

    Expected Behavior

    RedisPipelineException thrown intentionally inside closePipeline() should propagate directly without re-wrapping.

    Fix

    } catch (RedisPipelineException ex) {
    throw ex;
    } catch (Exception ex) {
    throw new RedisPipelineException(ex);
    }

Addendum

The default message "Pipeline contained one or more invalid commands" is hardcoded in the RedisPipelineException(Exception cause) constructor.

This message is misleading when the actual cause is a timeout rather than an invalid command. Whether this message should also be improved is left for further discussion.

Closes #3346

…Pipeline().

The catch (Exception ex) block in closePipeline() was too broad, catching intentionally thrown RedisPipelineExceptions and re-wrapping them with the misleading default message "Pipeline contained one or more invalid commands". Introduce a dedicated catch (RedisPipelineException ex) block to propagate the original exception directly.

  Closes spring-projects#3346

Signed-off-by: JEONGJAEIK <wodlr1207@naver.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RedisPipelineException is double-wrapped in LettuceConnection.closePipeline()

2 participants