apereo/cas · warning

Recovering From Exception thrown by

Error message

Recovering From Exception thrown by [{}]

What it means

AbstractAggregatingDefaultQueryPersonAttributeDao caught an exception thrown by one of its aggregated PersonAttributeDao sources. When recoverExceptions is true it only logs 'Recovering From Exception thrown by [...]' and continues with remaining DAOs; when false it rethrows (the 'Failing From' branch). The WARN indicates a source DAO failed but the aggregation survived.

Solutions

  1. Fix the underlying source DAO failure — read the attached 'ex' cause in the log for the real error (connection, credentials, query)
  2. If the failing repository should be optional, keep recoverExceptions=true; otherwise set recover-exceptions=false to fail fast
  3. Verify each attribute repository's connectivity/health independently before startup

Example fix

// before
cas.authn.attribute-repository.recover-exceptions=true
// after
cas.authn.attribute-repository.recover-exceptions=false # fail fast to expose the broken DAO
Defensive patterns

Strategy: retry

Validate before calling

// health-check each DAO before queries: dao.getPossibleUserAttributeNames() in a try block

Try / catch

try { people = aggregatingDao.getPeopleWithMultivaluedAttributes(query); } catch (RuntimeException e) { log.warn("all sources failed", e); people = Set.of(); }

Prevention

When it happens

Trigger: A nested PersonAttributeDao (JDBC, LDAP, REST, etc.) throws during getPeopleWithMultivaluedAttributes, getPossibleUserAttributeNames, or getAvailableQueryAttributes while recoverExceptions=true.

Common situations: One attribute repository backend is down (DB connection refused, LDAP timeout) while others work; misconfigured DAO credentials; schema/query error in a single source.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/a5d0461757c1d107. Report an issue: GitHub.

Appendix: source

Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/attribute/AbstractAggregatingDefaultQueryPersonAttributeDao.java:114

            }

            if (this.stopOnSuccess && !handledException) {
                LOGGER.debug("Successfully retrieved attributes from a child DAO and stopOnSuccess is true, stopping iteration of child DAOs");
                break;
            }
        }

        if (results == null) {
            return null;
        }

        LOGGER.debug("Aggregated search results [{}] for query [{}]", results, query);
        return Set.copyOf(results);
    }

    private boolean handleRuntimeException(final PersonAttributeDao currentlyConsidering, final Exception ex) {
        if (this.recoverExceptions) {
            LOGGER.warn("Recovering From Exception thrown by [{}]", currentlyConsidering, ex);
            return true;
        }
        LOGGER.error("Failing From Exception thrown by [{}]", currentlyConsidering, ex);
        throw ex instanceof final RuntimeException rte ? rte : new RuntimeException(ex);
    }


    /**
     * Call to execute the appropriate query on the current {@link PersonAttributeDao}. Provides extra information
     * beyond the seed for the state of the query chain and previous results.
     *
     * @param seed                 The seed for the original query.
     * @param isFirstQuery         If this is the first query, this will stay true until a call to this method returns (does not throw an exception).
     * @param currentlyConsidering The {@link PersonAttributeDao} to execute the query on.
     * @param resultPeople         The Map of results from all previous queries, may be null.
     * @param filter               the filter
     * @return The results from the call to the DAO.
     */

View on GitHub (pinned to e7288fc434)