@Override protected FailureAnalysis analyze(Throwable rootFailure, Bucket4jGeneralException cause) { String descriptionMessage = cause.getMessage(); String actionMessage = cause.getMessage(); if(cause instanceof JCacheNotFoundException) { JCacheNotFoundException ex = (JCacheNotFoundException) cause; descriptionMessage = "The cache name name defined in the property is not configured in the caching provider"; actionMessage = "Cache name: " + ex.getCacheName() + newline + "Please configure your caching provider (ehcache, hazelcast, ...)"; } if(cause instanceof MissingKeyFilterExpressionException) { descriptionMessage = "You've set the 'filter-key-type' to 'expression' but didn't set the property 'expression'"; actionMessage = "Please set the property 'expression' in your configuration file with a valid expression (see Spring Expression Language)" + newline; } return new FailureAnalysis(descriptionMessage, actionMessage, cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, QuickFixJBaseException cause) { String descriptionMessage = cause.getMessage(); String actionMessage = cause.getMessage(); if(cause instanceof ConfigurationException) { descriptionMessage = "A configuration error has been detected in the QuickFixJ settings provided."; actionMessage = "Please configure your QuickFixJ settings as per the documentation: https://www.quickfixj.org/usermanual/1.6.4//usage/configuration.html"; } if(cause instanceof SettingsNotFoundException) { descriptionMessage = "The QuickFixJ settings file could be found."; actionMessage = "Please provide a QuickFixJ settings file on the property 'config' for the client/server section in your configuration file."; } return new FailureAnalysis(descriptionMessage, actionMessage, cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, BeanCurrentlyInCreationException cause) { List<String> beansInCycle = new ArrayList<String>(); Throwable candidate = rootFailure; while (candidate != null) { if (candidate instanceof BeanCreationException) { BeanCreationException creationEx = (BeanCreationException) candidate; if (StringUtils.hasText(creationEx.getBeanName())) { beansInCycle .add(creationEx.getBeanName() + getDescription(creationEx)); } } candidate = candidate.getCause(); } StringBuilder message = new StringBuilder(); int uniqueBeans = beansInCycle.size() - 1; message.append( String.format("There is a circular dependency between %s beans in the " + "application context:%n", uniqueBeans)); for (String bean : beansInCycle) { message.append(String.format("\t- %s%n", bean)); } return new FailureAnalysis(message.toString(), null, cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, BindException cause) { if (CollectionUtils.isEmpty(cause.getFieldErrors())) { return null; } StringBuilder description = new StringBuilder( String.format("Binding to target %s failed:%n", cause.getTarget())); for (FieldError fieldError : cause.getFieldErrors()) { description.append(String.format("%n Property: %s", cause.getObjectName() + "." + fieldError.getField())); description.append( String.format("%n Value: %s", fieldError.getRejectedValue())); description.append( String.format("%n Reason: %s%n", fieldError.getDefaultMessage())); } return new FailureAnalysis(description.toString(), "Update your application's configuration", cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, WicketDependencyMismatchDetectedException cause) { String descriptionMessage = "One or more Wicket dependencies (jars) doesn't match the wicket-core dependency.\n\r" +"Wicket Core Version: " + cause.getWicketCoreVersion() + newline; for(MavenDependency dependency :cause.getDependencies()) { descriptionMessage += "\t" + dependency + newline; } String actionMessage = "Please check the Wicket versions configured in your dependency management system (Maven, Gradle, ...) " + newline + "You can disable this check via the property:" + newline + "\twicket.verifier.dependencies.enabled=false." + newline + "You can prevent throwing the exception but still log the detected problems via the property:" + newline + "\twicket.verifier.dependencies.throw-exception-on-dependency-version-mismatch=false"; return new FailureAnalysis(descriptionMessage, actionMessage, cause); }
@Test public void shouldAnalyzeConfigurationException() { // Given QuickFixJAutoConfigFailureAnalyzer analyzer = new QuickFixJAutoConfigFailureAnalyzer(); ConfigurationException exception = new ConfigurationException("Error", new RuntimeException()); // When FailureAnalysis analyze = analyzer.analyze(null, exception); assertThat(analyze.getAction()).contains("Please configure your QuickFixJ settings"); assertThat(analyze.getDescription()).contains("A configuration error has been detected in the QuickFixJ settings provided."); assertThat(analyze.getCause()).isEqualTo(exception); }
@Test public void shouldAnalyzeSettingsNotFoundException() { // Given QuickFixJAutoConfigFailureAnalyzer analyzer = new QuickFixJAutoConfigFailureAnalyzer(); SettingsNotFoundException exception = new SettingsNotFoundException("Error", new RuntimeException()); // When FailureAnalysis analyze = analyzer.analyze(null, exception); assertThat(analyze.getAction()).contains("Please provide a QuickFixJ settings file"); assertThat(analyze.getDescription()).contains("The QuickFixJ settings file could be found."); assertThat(analyze.getCause()).isEqualTo(exception); }
@Test public void shouldAnalyzeAnyException() { // Given QuickFixJAutoConfigFailureAnalyzer analyzer = new QuickFixJAutoConfigFailureAnalyzer(); QuickFixJBaseException exception = new QuickFixJBaseException("Error message", new RuntimeException()); // When FailureAnalysis analyze = analyzer.analyze(null, exception); assertThat(analyze.getAction()).contains("Error message"); assertThat(analyze.getDescription()).contains("Error message"); assertThat(analyze.getCause()).isEqualTo(exception); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, ConfigurationException cause) { String message = cause.getMessage(); if (cause.getDetailedMessage().isPresent()) { message += " - " + cause.getDetailedMessage().get(); } return new FailureAnalysis(message, "Double check the key value", cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, PortInUseException cause) { return new FailureAnalysis( "Embedded servlet container failed to start. Port " + cause.getPort() + " was already in use.", "Identify and stop the process that's listening on port " + cause.getPort() + " or configure this " + "application to listen on another port.", cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, ValidationException cause) { if (cause.getMessage().startsWith(MISSING_IMPLEMENTATION_MESSAGE)) { return new FailureAnalysis( "The Bean Validation API is on the classpath but no implementation" + " could be found", "Add an implementation, such as Hibernate Validator, to the" + " classpath", cause); } return null; }
@Override protected FailureAnalysis analyze(Throwable rootFailure, BeanNotOfRequiredTypeException cause) { if (!Proxy.isProxyClass(cause.getActualType())) { return null; } return new FailureAnalysis(getDescription(cause), ACTION, cause); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, NoUniqueBeanDefinitionException cause) { String consumerDescription = getConsumerDescription(rootFailure); if (consumerDescription == null) { return null; } String[] beanNames = extractBeanNames(cause); if (beanNames == null) { return null; } StringBuilder message = new StringBuilder(); message.append(String.format("%s required a single bean, but %d were found:%n", consumerDescription, beanNames.length)); for (String beanName : beanNames) { try { BeanDefinition beanDefinition = this.beanFactory .getMergedBeanDefinition(beanName); if (StringUtils.hasText(beanDefinition.getFactoryMethodName())) { message.append(String.format("\t- %s: defined by method '%s' in %s%n", beanName, beanDefinition.getFactoryMethodName(), beanDefinition.getResourceDescription())); } else { message.append(String.format("\t- %s: defined in %s%n", beanName, beanDefinition.getResourceDescription())); } } catch (NoSuchBeanDefinitionException ex) { message.append(String.format( "\t- %s: a programmatically registered singleton", beanName)); } } return new FailureAnalysis(message.toString(), "Consider marking one of the beans as @Primary, updating the consumer to" + " accept multiple beans, or using @Qualifier to identify the" + " bean that should be consumed", cause); }
@Test public void bindExceptionDueToValidationFailure() { FailureAnalysis analysis = performAnalysis(ValidationFailureConfiguration.class); assertThat(analysis.getDescription()) .contains(failure("test.foo.foo", "null", "may not be null")); assertThat(analysis.getDescription()) .contains(failure("test.foo.value", "0", "at least five")); assertThat(analysis.getDescription()) .contains(failure("test.foo.nested.bar", "null", "may not be null")); }
@Test public void cyclicBeanMethods() { FailureAnalysis analysis = performAnalysis(CyclicBeanMethodsConfiguration.class); assertThat(analysis.getDescription()).startsWith( "There is a circular dependency between 3 beans in the application context:"); assertThat(analysis.getDescription()).contains( "one defined in " + CyclicBeanMethodsConfiguration.class.getName()); assertThat(analysis.getDescription()).contains( "two defined in " + CyclicBeanMethodsConfiguration.class.getName()); assertThat(analysis.getDescription()).contains( "three defined in " + CyclicBeanMethodsConfiguration.class.getName()); }
@Test public void cycleWithAutowiredFields() { FailureAnalysis analysis = performAnalysis(CycleWithAutowiredFields.class); assertThat(analysis.getDescription()).startsWith( "There is a circular dependency between 3 beans in the application context:"); assertThat(analysis.getDescription()).contains("three defined in " + CycleWithAutowiredFields.BeanThreeConfiguration.class.getName()); assertThat(analysis.getDescription()) .contains("one defined in " + CycleWithAutowiredFields.class.getName()); assertThat(analysis.getDescription()) .contains(CycleWithAutowiredFields.BeanTwoConfiguration.class.getName() + " (field private " + BeanThree.class.getName()); }
@Test public void test() throws Exception { try { new AnnotationConfigApplicationContext(TestConfiguration.class).close(); fail("Expected failure did not occur"); } catch (Exception ex) { FailureAnalysis analysis = new ValidationExceptionFailureAnalyzer() .analyze(ex); assertThat(analysis).isNotNull(); } }
@Test public void failureAnalysisForFieldConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(FieldConsumer.class)); assertThat(failureAnalysis.getDescription()) .startsWith("Field testBean in " + FieldConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
@Test public void failureAnalysisForMethodConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(MethodConsumer.class)); assertThat(failureAnalysis.getDescription()).startsWith( "Parameter 0 of method consumer in " + MethodConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
@Test public void failureAnalysisForConstructorConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(ConstructorConsumer.class)); assertThat(failureAnalysis.getDescription()).startsWith( "Parameter 0 of constructor in " + ConstructorConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
@Test public void failureAnalysisForObjectProviderMethodConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(ObjectProviderMethodConsumer.class)); assertThat(failureAnalysis.getDescription()).startsWith( "Method consumer in " + ObjectProviderMethodConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
@Test public void failureAnalysisForXmlConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(XmlConsumer.class)); assertThat(failureAnalysis.getDescription()).startsWith( "Parameter 0 of constructor in " + TestBeanConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
@Test public void failureAnalysisForObjectProviderConstructorConsumer() { FailureAnalysis failureAnalysis = analyzeFailure( createFailure(ObjectProviderConstructorConsumer.class)); assertThat(failureAnalysis.getDescription()).startsWith( "Constructor in " + ObjectProviderConstructorConsumer.class.getName() + " required a single bean, but 6 were found:"); assertFoundBeans(failureAnalysis); }
private void assertFoundBeans(FailureAnalysis analysis) { assertThat(analysis.getDescription()) .contains("beanOne: defined by method 'beanOne' in " + DuplicateBeansProducer.class.getName()); assertThat(analysis.getDescription()) .contains("beanTwo: defined by method 'beanTwo' in " + DuplicateBeansProducer.class.getName()); assertThat(analysis.getDescription()) .contains("beanThree: defined by method 'beanThree' in " + ParentProducer.class.getName()); assertThat(analysis.getDescription()).contains("barTestBean"); assertThat(analysis.getDescription()).contains("fooTestBean"); assertThat(analysis.getDescription()).contains("xmlTestBean"); }
@Test public void jdkProxyCausesInjectionFailure() { FailureAnalysis analysis = performAnalysis(JdkProxyConfiguration.class); assertThat(analysis.getDescription()).startsWith("The bean 'asyncBean'"); assertThat(analysis.getDescription()) .contains("'" + AsyncBean.class.getName() + "'"); assertThat(analysis.getDescription()) .endsWith(String.format("%s%n", SomeInterface.class.getName())); }
@Override protected FailureAnalysis analyze(Throwable rootFailure, DataSourceBeanCreationException cause) { String message = cause.getMessage(); String description = message.substring(0, message.indexOf(".")).trim(); String action = message.substring(message.indexOf(".") + 1).trim(); return new FailureAnalysis(description, action, cause); }
@Test public void failureAnalysisIsPerformed() { FailureAnalysis failureAnalysis = performAnalysis(TestConfiguration.class); assertThat(failureAnalysis.getDescription()).isEqualTo( "Cannot determine embedded database driver class for database type NONE"); assertThat(failureAnalysis.getAction()).isEqualTo("If you want an embedded " + "database please put a supported one on the classpath. If you have " + "database settings to be loaded from a particular profile you may " + "need to active it (no profiles are currently active)."); }