{"record":{"id":"a5d0461757c1d107","repo":"apereo/cas","slug":"recovering-from-exception-thrown-by","errorCode":null,"errorMessage":"Recovering From Exception thrown by [{}]","messagePattern":"Recovering From Exception thrown by \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/attribute/AbstractAggregatingDefaultQueryPersonAttributeDao.java","lineNumber":114,"sourceCode":"            }\n\n            if (this.stopOnSuccess && !handledException) {\n                LOGGER.debug(\"Successfully retrieved attributes from a child DAO and stopOnSuccess is true, stopping iteration of child DAOs\");\n                break;\n            }\n        }\n\n        if (results == null) {\n            return null;\n        }\n\n        LOGGER.debug(\"Aggregated search results [{}] for query [{}]\", results, query);\n        return Set.copyOf(results);\n    }\n\n    private boolean handleRuntimeException(final PersonAttributeDao currentlyConsidering, final Exception ex) {\n        if (this.recoverExceptions) {\n            LOGGER.warn(\"Recovering From Exception thrown by [{}]\", currentlyConsidering, ex);\n            return true;\n        }\n        LOGGER.error(\"Failing From Exception thrown by [{}]\", currentlyConsidering, ex);\n        throw ex instanceof final RuntimeException rte ? rte : new RuntimeException(ex);\n    }\n\n\n    /**\n     * Call to execute the appropriate query on the current {@link PersonAttributeDao}. Provides extra information\n     * beyond the seed for the state of the query chain and previous results.\n     *\n     * @param seed                 The seed for the original query.\n     * @param isFirstQuery         If this is the first query, this will stay true until a call to this method returns (does not throw an exception).\n     * @param currentlyConsidering The {@link PersonAttributeDao} to execute the query on.\n     * @param resultPeople         The Map of results from all previous queries, may be null.\n     * @param filter               the filter\n     * @return The results from the call to the DAO.\n     */","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/attribute/AbstractAggregatingDefaultQueryPersonAttributeDao.java#L96-L132","documentation":"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.","triggerScenarios":"A nested PersonAttributeDao (JDBC, LDAP, REST, etc.) throws during getPeopleWithMultivaluedAttributes, getPossibleUserAttributeNames, or getAvailableQueryAttributes while recoverExceptions=true.","commonSituations":"One attribute repository backend is down (DB connection refused, LDAP timeout) while others work; misconfigured DAO credentials; schema/query error in a single source.","solutions":["Fix the underlying source DAO failure — read the attached 'ex' cause in the log for the real error (connection, credentials, query)","If the failing repository should be optional, keep recoverExceptions=true; otherwise set recover-exceptions=false to fail fast","Verify each attribute repository's connectivity/health independently before startup"],"exampleFix":"// before\ncas.authn.attribute-repository.recover-exceptions=true\n// after\ncas.authn.attribute-repository.recover-exceptions=false # fail fast to expose the broken DAO","handlingStrategy":"retry","validationCode":"// health-check each DAO before queries: dao.getPossibleUserAttributeNames() in a try block","typeGuard":null,"tryCatchPattern":"try { people = aggregatingDao.getPeopleWithMultivaluedAttributes(query); } catch (RuntimeException e) { log.warn(\"all sources failed\", e); people = Set.of(); }","preventionTips":["Keep recoverExceptions=true if repositories are optional","Monitor WARN logs for recurring source failures","Set per-DAO timeouts so a slow source fails fast"],"tags":["attribute-repository","person-attribute-dao","graceful-degradation","jdbc","ldap"],"backgroundTag":"database-query-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}