Cleaned up profile loading exceptions.
This commit is contained in:
parent
48dc4fd9e7
commit
a7654e49ca
|
@ -2,8 +2,7 @@ package com.andrewlalis.perfin;
|
||||||
|
|
||||||
import com.andrewlalis.javafx_scene_router.AnchorPaneRouterView;
|
import com.andrewlalis.javafx_scene_router.AnchorPaneRouterView;
|
||||||
import com.andrewlalis.javafx_scene_router.SceneRouter;
|
import com.andrewlalis.javafx_scene_router.SceneRouter;
|
||||||
import com.andrewlalis.perfin.control.Popups;
|
import com.andrewlalis.perfin.data.ProfileLoadException;
|
||||||
import com.andrewlalis.perfin.data.DataSourceInitializationException;
|
|
||||||
import com.andrewlalis.perfin.model.Profile;
|
import com.andrewlalis.perfin.model.Profile;
|
||||||
import com.andrewlalis.perfin.view.ImageCache;
|
import com.andrewlalis.perfin.view.ImageCache;
|
||||||
import com.andrewlalis.perfin.view.SceneUtil;
|
import com.andrewlalis.perfin.view.SceneUtil;
|
||||||
|
@ -93,8 +92,8 @@ public class PerfinApp extends Application {
|
||||||
msgConsumer.accept("Loading the most recent profile.");
|
msgConsumer.accept("Loading the most recent profile.");
|
||||||
try {
|
try {
|
||||||
Profile.loadLast();
|
Profile.loadLast();
|
||||||
} catch (DataSourceInitializationException e) {
|
} catch (ProfileLoadException e) {
|
||||||
Popups.error(e.getMessage());
|
msgConsumer.accept("Failed to load the profile: " + e.getMessage());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.andrewlalis.perfin.control;
|
package com.andrewlalis.perfin.control;
|
||||||
|
|
||||||
import com.andrewlalis.perfin.PerfinApp;
|
import com.andrewlalis.perfin.PerfinApp;
|
||||||
import com.andrewlalis.perfin.data.DataSourceInitializationException;
|
import com.andrewlalis.perfin.data.ProfileLoadException;
|
||||||
import com.andrewlalis.perfin.data.util.FileUtil;
|
import com.andrewlalis.perfin.data.util.FileUtil;
|
||||||
import com.andrewlalis.perfin.model.Profile;
|
import com.andrewlalis.perfin.model.Profile;
|
||||||
import com.andrewlalis.perfin.view.ProfilesStage;
|
import com.andrewlalis.perfin.view.ProfilesStage;
|
||||||
|
@ -121,12 +121,8 @@ public class ProfilesViewController {
|
||||||
router.navigate("accounts");
|
router.navigate("accounts");
|
||||||
if (showPopup) Popups.message("The profile \"" + name + "\" has been loaded.");
|
if (showPopup) Popups.message("The profile \"" + name + "\" has been loaded.");
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (ProfileLoadException e) {
|
||||||
e.printStackTrace(System.err);
|
Popups.error("Failed to load the profile: " + e.getMessage());
|
||||||
Popups.error("Failed to load profile: " + e.getMessage());
|
|
||||||
return false;
|
|
||||||
} catch (DataSourceInitializationException e) {
|
|
||||||
Popups.error("Failed to initialize the profile's data: " + e.getMessage());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.andrewlalis.perfin.data;
|
|
||||||
|
|
||||||
public class DataSourceInitializationException extends Exception {
|
|
||||||
public DataSourceInitializationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataSourceInitializationException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.andrewlalis.perfin.data;
|
||||||
|
|
||||||
|
public class ProfileLoadException extends Exception {
|
||||||
|
public ProfileLoadException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileLoadException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package com.andrewlalis.perfin.data.impl;
|
package com.andrewlalis.perfin.data.impl;
|
||||||
|
|
||||||
import com.andrewlalis.perfin.data.DataSource;
|
import com.andrewlalis.perfin.data.DataSource;
|
||||||
import com.andrewlalis.perfin.data.DataSourceInitializationException;
|
import com.andrewlalis.perfin.data.ProfileLoadException;
|
||||||
import com.andrewlalis.perfin.data.util.FileUtil;
|
import com.andrewlalis.perfin.data.util.FileUtil;
|
||||||
import com.andrewlalis.perfin.model.Profile;
|
import com.andrewlalis.perfin.model.Profile;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -32,7 +32,7 @@ public class JdbcDataSourceFactory {
|
||||||
*/
|
*/
|
||||||
public static final int SCHEMA_VERSION = 1;
|
public static final int SCHEMA_VERSION = 1;
|
||||||
|
|
||||||
public DataSource getDataSource(String profileName) throws DataSourceInitializationException {
|
public DataSource getDataSource(String profileName) throws ProfileLoadException {
|
||||||
final boolean dbExists = Files.exists(getDatabaseFile(profileName));
|
final boolean dbExists = Files.exists(getDatabaseFile(profileName));
|
||||||
if (!dbExists) {
|
if (!dbExists) {
|
||||||
log.info("Creating new database for profile {}.", profileName);
|
log.info("Creating new database for profile {}.", profileName);
|
||||||
|
@ -43,7 +43,7 @@ public class JdbcDataSourceFactory {
|
||||||
loadedSchemaVersion = getSchemaVersion(profileName);
|
loadedSchemaVersion = getSchemaVersion(profileName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Failed to load schema version.", e);
|
log.error("Failed to load schema version.", e);
|
||||||
throw new DataSourceInitializationException("Failed to determine database schema version.", e);
|
throw new ProfileLoadException("Failed to determine database schema version.", e);
|
||||||
}
|
}
|
||||||
log.debug("Database loaded for profile {} has schema version {}.", profileName, loadedSchemaVersion);
|
log.debug("Database loaded for profile {} has schema version {}.", profileName, loadedSchemaVersion);
|
||||||
if (loadedSchemaVersion < SCHEMA_VERSION) {
|
if (loadedSchemaVersion < SCHEMA_VERSION) {
|
||||||
|
@ -51,13 +51,13 @@ public class JdbcDataSourceFactory {
|
||||||
// TODO: Do migration
|
// TODO: Do migration
|
||||||
} else if (loadedSchemaVersion > SCHEMA_VERSION) {
|
} else if (loadedSchemaVersion > SCHEMA_VERSION) {
|
||||||
log.debug("Schema version {} is higher than the app's version {}. Cannot continue.", loadedSchemaVersion, SCHEMA_VERSION);
|
log.debug("Schema version {} is higher than the app's version {}. Cannot continue.", loadedSchemaVersion, SCHEMA_VERSION);
|
||||||
throw new DataSourceInitializationException("Profile " + profileName + " has a database with an unsupported schema version.");
|
throw new ProfileLoadException("Profile " + profileName + " has a database with an unsupported schema version.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new JdbcDataSource(getJdbcUrl(profileName), Profile.getContentDir(profileName));
|
return new JdbcDataSource(getJdbcUrl(profileName), Profile.getContentDir(profileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNewDatabase(String profileName) throws DataSourceInitializationException {
|
private void createNewDatabase(String profileName) throws ProfileLoadException {
|
||||||
log.info("Creating new database for profile {}.", profileName);
|
log.info("Creating new database for profile {}.", profileName);
|
||||||
JdbcDataSource dataSource = new JdbcDataSource(getJdbcUrl(profileName), Profile.getContentDir(profileName));
|
JdbcDataSource dataSource = new JdbcDataSource(getJdbcUrl(profileName), Profile.getContentDir(profileName));
|
||||||
try (
|
try (
|
||||||
|
@ -81,15 +81,15 @@ public class JdbcDataSourceFactory {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("IO Exception when trying to create database.", e);
|
log.error("IO Exception when trying to create database.", e);
|
||||||
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
||||||
throw new DataSourceInitializationException("Failed to read SQL data to create database schema.", e);
|
throw new ProfileLoadException("Failed to read SQL data to create database schema.", e);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("SQL Exception when trying to create database.", e);
|
log.error("SQL Exception when trying to create database.", e);
|
||||||
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
||||||
throw new DataSourceInitializationException("Failed to create the database due to an SQL error.", e);
|
throw new ProfileLoadException("Failed to create the database due to an SQL error.", e);
|
||||||
}
|
}
|
||||||
if (!testConnection(dataSource)) {
|
if (!testConnection(dataSource)) {
|
||||||
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
FileUtil.deleteIfPossible(getDatabaseFile(profileName));
|
||||||
throw new DataSourceInitializationException("Testing the database connection failed.");
|
throw new ProfileLoadException("Testing the database connection failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,11 @@ public class JdbcDataSourceFactory {
|
||||||
|
|
||||||
private static int getSchemaVersion(String profileName) throws IOException {
|
private static int getSchemaVersion(String profileName) throws IOException {
|
||||||
if (Files.exists(getSchemaVersionFile(profileName))) {
|
if (Files.exists(getSchemaVersionFile(profileName))) {
|
||||||
return Integer.parseInt(Files.readString(getSchemaVersionFile(profileName)));
|
try {
|
||||||
|
return Integer.parseInt(Files.readString(getSchemaVersionFile(profileName)).strip());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IOException("Could not parse integer schema version.", e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
writeCurrentSchemaVersion(profileName);
|
writeCurrentSchemaVersion(profileName);
|
||||||
return SCHEMA_VERSION;
|
return SCHEMA_VERSION;
|
||||||
|
|
|
@ -37,9 +37,13 @@ public class FileUtil {
|
||||||
|
|
||||||
public static void deleteIfPossible(Path file) {
|
public static void deleteIfPossible(Path file) {
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(file);
|
if (Files.isDirectory(file)) {
|
||||||
|
deleteDirRecursive(file);
|
||||||
|
} else {
|
||||||
|
Files.deleteIfExists(file);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Failed to delete file " + file, e);
|
log.error("Failed to delete " + file, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ package com.andrewlalis.perfin.model;
|
||||||
|
|
||||||
import com.andrewlalis.perfin.PerfinApp;
|
import com.andrewlalis.perfin.PerfinApp;
|
||||||
import com.andrewlalis.perfin.data.DataSource;
|
import com.andrewlalis.perfin.data.DataSource;
|
||||||
import com.andrewlalis.perfin.data.DataSourceInitializationException;
|
import com.andrewlalis.perfin.data.ProfileLoadException;
|
||||||
import com.andrewlalis.perfin.data.impl.JdbcDataSourceFactory;
|
import com.andrewlalis.perfin.data.impl.JdbcDataSourceFactory;
|
||||||
|
import com.andrewlalis.perfin.data.util.FileUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -118,17 +119,24 @@ public class Profile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadLast() throws IOException, DataSourceInitializationException {
|
public static void loadLast() throws ProfileLoadException {
|
||||||
load(getLastProfile());
|
load(getLastProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void load(String name) throws IOException, DataSourceInitializationException {
|
public static void load(String name) throws ProfileLoadException {
|
||||||
if (Files.notExists(getDir(name))) {
|
if (Files.notExists(getDir(name))) {
|
||||||
initProfileDir(name);
|
try {
|
||||||
|
initProfileDir(name);
|
||||||
|
} catch (IOException e) {
|
||||||
|
FileUtil.deleteIfPossible(getDir(name));
|
||||||
|
throw new ProfileLoadException("Failed to initialize new profile directory.", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Properties settings = new Properties();
|
Properties settings = new Properties();
|
||||||
try (var in = Files.newInputStream(getSettingsFile(name))) {
|
try (var in = Files.newInputStream(getSettingsFile(name))) {
|
||||||
settings.load(in);
|
settings.load(in);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ProfileLoadException("Failed to load profile settings.", e);
|
||||||
}
|
}
|
||||||
current = new Profile(name, settings, new JdbcDataSourceFactory().getDataSource(name));
|
current = new Profile(name, settings, new JdbcDataSourceFactory().getDataSource(name));
|
||||||
saveLastProfile(current.getName());
|
saveLastProfile(current.getName());
|
||||||
|
|
|
@ -66,6 +66,11 @@ public class StartupSplashScreen extends Stage implements Consumer<String> {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
accept("Startup failed: " + e.getMessage());
|
accept("Startup failed: " + e.getMessage());
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
Platform.runLater(this::close);
|
Platform.runLater(this::close);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue