Cleaned up profile loading exceptions.

This commit is contained in:
Andrew Lalis 2024-01-03 15:20:34 -05:00
parent 48dc4fd9e7
commit a7654e49ca
8 changed files with 53 additions and 37 deletions

View File

@ -2,8 +2,7 @@ package com.andrewlalis.perfin;
import com.andrewlalis.javafx_scene_router.AnchorPaneRouterView;
import com.andrewlalis.javafx_scene_router.SceneRouter;
import com.andrewlalis.perfin.control.Popups;
import com.andrewlalis.perfin.data.DataSourceInitializationException;
import com.andrewlalis.perfin.data.ProfileLoadException;
import com.andrewlalis.perfin.model.Profile;
import com.andrewlalis.perfin.view.ImageCache;
import com.andrewlalis.perfin.view.SceneUtil;
@ -93,8 +92,8 @@ public class PerfinApp extends Application {
msgConsumer.accept("Loading the most recent profile.");
try {
Profile.loadLast();
} catch (DataSourceInitializationException e) {
Popups.error(e.getMessage());
} catch (ProfileLoadException e) {
msgConsumer.accept("Failed to load the profile: " + e.getMessage());
throw e;
}
}

View File

@ -1,7 +1,7 @@
package com.andrewlalis.perfin.control;
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.model.Profile;
import com.andrewlalis.perfin.view.ProfilesStage;
@ -121,12 +121,8 @@ public class ProfilesViewController {
router.navigate("accounts");
if (showPopup) Popups.message("The profile \"" + name + "\" has been loaded.");
return true;
} catch (IOException e) {
e.printStackTrace(System.err);
Popups.error("Failed to load profile: " + e.getMessage());
return false;
} catch (DataSourceInitializationException e) {
Popups.error("Failed to initialize the profile's data: " + e.getMessage());
} catch (ProfileLoadException e) {
Popups.error("Failed to load the profile: " + e.getMessage());
return false;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -1,7 +1,7 @@
package com.andrewlalis.perfin.data.impl;
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.model.Profile;
import org.slf4j.Logger;
@ -32,7 +32,7 @@ public class JdbcDataSourceFactory {
*/
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));
if (!dbExists) {
log.info("Creating new database for profile {}.", profileName);
@ -43,7 +43,7 @@ public class JdbcDataSourceFactory {
loadedSchemaVersion = getSchemaVersion(profileName);
} catch (IOException 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);
if (loadedSchemaVersion < SCHEMA_VERSION) {
@ -51,13 +51,13 @@ public class JdbcDataSourceFactory {
// TODO: Do migration
} else if (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));
}
private void createNewDatabase(String profileName) throws DataSourceInitializationException {
private void createNewDatabase(String profileName) throws ProfileLoadException {
log.info("Creating new database for profile {}.", profileName);
JdbcDataSource dataSource = new JdbcDataSource(getJdbcUrl(profileName), Profile.getContentDir(profileName));
try (
@ -81,15 +81,15 @@ public class JdbcDataSourceFactory {
} catch (IOException e) {
log.error("IO Exception when trying to create database.", e);
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) {
log.error("SQL Exception when trying to create database.", e);
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)) {
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 {
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 {
writeCurrentSchemaVersion(profileName);
return SCHEMA_VERSION;

View File

@ -37,9 +37,13 @@ public class FileUtil {
public static void deleteIfPossible(Path file) {
try {
if (Files.isDirectory(file)) {
deleteDirRecursive(file);
} else {
Files.deleteIfExists(file);
}
} catch (IOException e) {
log.error("Failed to delete file " + file, e);
log.error("Failed to delete " + file, e);
}
}

View File

@ -2,8 +2,9 @@ package com.andrewlalis.perfin.model;
import com.andrewlalis.perfin.PerfinApp;
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.util.FileUtil;
import org.slf4j.Logger;
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());
}
public static void load(String name) throws IOException, DataSourceInitializationException {
public static void load(String name) throws ProfileLoadException {
if (Files.notExists(getDir(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();
try (var in = Files.newInputStream(getSettingsFile(name))) {
settings.load(in);
} catch (IOException e) {
throw new ProfileLoadException("Failed to load profile settings.", e);
}
current = new Profile(name, settings, new JdbcDataSourceFactory().getDataSource(name));
saveLastProfile(current.getName());

View File

@ -66,6 +66,11 @@ public class StartupSplashScreen extends Stage implements Consumer<String> {
} catch (Exception e) {
accept("Startup failed: " + e.getMessage());
e.printStackTrace(System.err);
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
Platform.runLater(this::close);
return;
}