Skip to content

Introduce RedisNoFunctionException to represent Redis NOFUNCTION response #3717#3718

Open
hocaron wants to merge 1 commit intoredis:mainfrom
hocaron:feat/redis-no-function-exception
Open

Introduce RedisNoFunctionException to represent Redis NOFUNCTION response #3717#3718
hocaron wants to merge 1 commit intoredis:mainfrom
hocaron:feat/redis-no-function-exception

Conversation

@hocaron
Copy link
Copy Markdown

@hocaron hocaron commented Apr 11, 2026

Description

Introduces RedisNoFunctionException extending RedisCommandExecutionException
for ERR Function not found replies from FCALL / FCALL_RO. Mirrors the
existing pattern of RedisNoScriptException (#620), RedisLoadingException
(#682), and RedisReadOnlyException (#1943 / #1944).

Resolves #3717

Why a dedicated exception

Message string matching works functionally, but introduces several issues
that Lettuce has historically decided to solve with dedicated exception
types. The same reasoning applies here:

  1. Type safety: Catching RedisCommandExecutionException forces users
    to catch an extremely broad supertype (covering ERR, WRONGTYPE,
    OOM, MISCONF, CLUSTERDOWN, etc.) and filter inside. Easy to
    accidentally swallow unrelated errors.

  2. Stability contract: If the error literal is tracked in one place
    (ExceptionFactory), Lettuce can adapt to future Redis server changes
    without every user application breaking silently. Users who match
    messages themselves each maintain their own fragile copy.

  3. Consistency: NOSCRIPT, BUSY, LOADING, READONLY all have
    dedicated subtypes. NOFUNCTION is conceptually the same (a recoverable
    error requiring a fallback pattern); leaving it out is an asymmetric gap.

  4. Enables higher-level abstractions: Spring Data Redis's
    DefaultScriptExecutor currently uses
    ScriptUtils.exceptionContainsNoScriptError as a last resort because
    RedisNoScriptException exists. Without RedisNoFunctionException,
    any future DefaultRedisFunction in Spring Data Redis would have to
    reintroduce the same message-matching pattern. Providing the typed
    exception here keeps the ecosystem consistent.

  5. Testability: Unit tests for fallback logic can mock by type rather
    than by exact message format, which is more robust to Lettuce/Redis
    version changes.

These are the same arguments that led to #620, #682, and #1943 being
accepted. This PR follows the established pattern rather than proposing
a new direction.

Error message stability

The "ERR Function not found" literal originates from a single location in
Redis server (src/functions.c in fcallCommandGeneric) and has been
unchanged from Redis 7.0 through the current unstable branch. Verified
across Redis 7.0, 7.2, 7.4, and 8.0-M04. Other FUNCTION-related commands
emit distinct messages ("Library not found", "Engine '...' not found",
"Library '...' already exists", "Missing library metadata"), so
startsWith("ERR Function not found") is precise with no false-positive
risk.

Changes

  • RedisNoFunctionException.java (new) — subtype of
    RedisCommandExecutionException, mirrors RedisReadOnlyException
  • ExceptionFactory.createExecutionException — new mapping branch for
    "ERR Function not found" prefix
  • ExceptionFactoryUnitTests — unit tests for the new mapping, including
    a negative test that other ERR messages are not misclassified

Checklist


Note

Low Risk
Low risk: introduces a new exception subtype and a narrow message-to-exception mapping (ERR Function not found), with unit tests to prevent misclassification of other ERR messages.

Overview
Adds a new RedisNoFunctionException to represent Redis ERR Function not found errors from FCALL/FCALL_RO.

Updates ExceptionFactory.createExecutionException to return this new subtype when the error message starts with ERR Function not found, and extends ExceptionFactoryUnitTests to verify the mapping (including negative tests for other ERR ... not found messages).

Reviewed by Cursor Bugbot for commit 9829ce7. Bugbot is set up for automated code reviews on this repo. Configure here.

…onse redis#3717

Introduces RedisNoFunctionException extending RedisCommandExecutionException,
mirroring the pattern of RedisNoScriptException (redis#620), RedisLoadingException
(redis#682), and RedisReadOnlyException (redis#1943). ExceptionFactory now maps
"ERR Function not found" replies from FCALL/FCALL_RO to this new type,
enabling type-safe fallback implementations.

Signed-off-by: hocaron <kkannu0407@gmail.com>
@jit-ci
Copy link
Copy Markdown

jit-ci Bot commented Apr 11, 2026

Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset.

In case there are security findings, they will be communicated to you as a comment inside the PR.

Hope you’ll enjoy using Jit.

Questions? Comments? Want to learn more? Get in touch with us.

@atakavci
Copy link
Copy Markdown
Collaborator

atakavci commented May 4, 2026

hi @hocaron,

sorry its been a while.
i tried to explore around what would be the implications and ideal approach for the library.
And concluded that handling a server ERR via inspecting the message content would be sub-optimal.

There are cases we handle and turn into a specific exception type but, as i mentioned in the related issue entry, those are checking the initial word, which serves as a type code or unique exception type identifier.
In this case, the ERR message content is not part of any contract server exposes and will be subject to change in time or across the versions.
So the fundamental reasoning is library shouldn't rely on anything that is NOT part of the server contract and doing so -treating the message as part of contract- could easily lead to broken library behaviour and/or possible false positives in client app.

Any client app that would need to identify the ERR, should do so knowing the consequences, and the responsilbity is theirs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a RedisNoFunctionException for FCALL Function not found errors

2 participants