From d5ca3028e37cd6861d1eff6a2cd2e5609f8fdfd1 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 13 Aug 2013 17:48:50 +0200 Subject: [PATCH] SONAR-4547 API: new class "MessageException" to stop a pending process and to log an error message without any stack trace --- .../bootstrap/DatabaseCompatibility.java | 10 ++-- .../bootstrap/DatabaseCompatibilityTest.java | 10 ++-- .../org/sonar/api/utils/MessageException.java | 50 +++++++++++++++++++ .../sonar/api/utils/MessageExceptionTest.java | 50 +++++++++++++++++++ .../platform/DatabaseServerCompatibility.java | 4 +- .../DatabaseServerCompatibilityTest.java | 4 +- 6 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java create mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java index 6b373735b2a..26f0f425015 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java @@ -23,7 +23,7 @@ import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; -import org.sonar.core.persistence.BadDatabaseVersion; +import org.sonar.api.utils.MessageException; import org.sonar.core.persistence.DatabaseVersion; /** @@ -59,21 +59,21 @@ public class DatabaseCompatibility implements BatchComponent { message.append(" / *****)\n\t- Server side: check the configuration at "); message.append(server.getURL()); message.append("/system\n"); - throw new BadDatabaseVersion(message.toString()); + throw new MessageException(message.toString()); } } private void checkDatabaseStatus() { DatabaseVersion.Status status = version.getStatus(); if (status == DatabaseVersion.Status.REQUIRES_DOWNGRADE) { - throw new BadDatabaseVersion("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)"); + throw new MessageException("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)"); } if (status == DatabaseVersion.Status.REQUIRES_UPGRADE) { - throw new BadDatabaseVersion("Database must be upgraded. Please browse " + server.getURL() + "/setup"); + throw new MessageException("Database must be upgraded. Please browse " + server.getURL() + "/setup"); } if (status != DatabaseVersion.Status.UP_TO_DATE) { // Support other future values - throw new BadDatabaseVersion("Unknown database status: " + status); + throw new MessageException("Unknown database status: " + status); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java index 43677fa9ce4..673d422affe 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java @@ -26,7 +26,7 @@ import org.junit.rules.ExpectedException; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; -import org.sonar.core.persistence.BadDatabaseVersion; +import org.sonar.api.utils.MessageException; import org.sonar.core.persistence.DatabaseVersion; import static org.mockito.Mockito.mock; @@ -60,7 +60,7 @@ public class DatabaseCompatibilityTest { public void shouldFailIfRequiresDowngrade() { when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_DOWNGRADE); - thrown.expect(BadDatabaseVersion.class); + thrown.expect(MessageException.class); thrown.expectMessage("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)"); new DatabaseCompatibility(databaseVersion, server, settings).start(); @@ -70,7 +70,7 @@ public class DatabaseCompatibilityTest { public void shouldFailIfRequiresUpgrade() { when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_UPGRADE); - thrown.expect(BadDatabaseVersion.class); + thrown.expect(MessageException.class); thrown.expectMessage("Database must be upgraded."); new DatabaseCompatibility(databaseVersion, server, settings).start(); @@ -80,7 +80,7 @@ public class DatabaseCompatibilityTest { public void shouldFailIfNotSameServerId() throws Exception { settings.setProperty(CoreProperties.SERVER_ID, "11111111"); - thrown.expect(BadDatabaseVersion.class); + thrown.expect(MessageException.class); thrown.expectMessage("The current batch process and the configured remote server do not share the same DB configuration."); thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (bar / *****)"); thrown.expectMessage("- Server side: check the configuration at http://localhost:9000/system"); @@ -94,7 +94,7 @@ public class DatabaseCompatibilityTest { settings.removeProperty(DatabaseProperties.PROP_USER); - thrown.expect(BadDatabaseVersion.class); + thrown.expect(MessageException.class); thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (sonar / *****)"); new DatabaseCompatibility(databaseVersion, server, settings).start(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java new file mode 100644 index 00000000000..25290dac9b2 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/MessageException.java @@ -0,0 +1,50 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.utils; + +/** + * Runtime exception for "functional" errors. It aims to be displayed to end-users, without any technical information + * like stack traces. + * + * @since 4.0 + */ +public class MessageException extends RuntimeException { + + public MessageException(String s) { + super(s); + } + + /** + * Does not fill in the stack trace + * + * @see java.lang.Throwable#fillInStackTrace() + */ + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + + @Override + public String toString() { + return getMessage(); + } + + +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java new file mode 100644 index 00000000000..0b734416e94 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/MessageExceptionTest.java @@ -0,0 +1,50 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.utils; + +import org.junit.Test; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import static org.fest.assertions.Assertions.assertThat; + +public class MessageExceptionTest { + + /** + * The exception should log only the message, without the "org.sonar.api.utils.MessageException" prefix + * and stack traces + */ + @Test + public void should_not_print_stacktrace() throws Exception { + String message = "the message"; + try { + throw new MessageException(message); + + } catch (MessageException e) { + StringWriter writer = new StringWriter(); + e.printStackTrace(new PrintWriter(writer)); + + assertThat(e.getStackTrace()).isEmpty(); + assertThat(e.getMessage()).isEqualTo(message); + assertThat(writer.toString()).isEqualTo(message + System.getProperty("line.separator")); + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java b/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java index 798926ea2d0..a8fb1a922a4 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java @@ -21,7 +21,7 @@ package org.sonar.server.platform; import org.slf4j.LoggerFactory; import org.sonar.api.ServerComponent; -import org.sonar.core.persistence.BadDatabaseVersion; +import org.sonar.api.utils.MessageException; import org.sonar.core.persistence.DatabaseVersion; public class DatabaseServerCompatibility implements ServerComponent { @@ -35,7 +35,7 @@ public class DatabaseServerCompatibility implements ServerComponent { public void start() { DatabaseVersion.Status status = version.getStatus(); if (status== DatabaseVersion.Status.REQUIRES_DOWNGRADE) { - throw new BadDatabaseVersion("Database relates to a more recent version of sonar. Please check your settings."); + throw new MessageException("Database relates to a more recent version of sonar. Please check your settings."); } if (status== DatabaseVersion.Status.REQUIRES_UPGRADE) { LoggerFactory.getLogger(DatabaseServerCompatibility.class).info("Database must be upgraded. Please browse /setup"); diff --git a/sonar-server/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java b/sonar-server/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java index ae80f612c28..0d126ab7e95 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java @@ -20,7 +20,7 @@ package org.sonar.server.platform; import org.junit.Test; -import org.sonar.core.persistence.BadDatabaseVersion; +import org.sonar.api.utils.MessageException; import org.sonar.core.persistence.DatabaseVersion; import static org.mockito.Mockito.mock; @@ -28,7 +28,7 @@ import static org.mockito.Mockito.when; public class DatabaseServerCompatibilityTest { - @Test(expected = BadDatabaseVersion.class) + @Test(expected = MessageException.class) public void shouldFailIfRequiresDowngrade() { DatabaseVersion version = mock(DatabaseVersion.class); when(version.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_DOWNGRADE); -- 2.39.5