diff --git a/src/main/java/edu/byu/cs/analytics/CommitAnalytics.java b/src/main/java/edu/byu/cs/analytics/CommitAnalytics.java index 066677cd7..e294ebf74 100644 --- a/src/main/java/edu/byu/cs/analytics/CommitAnalytics.java +++ b/src/main/java/edu/byu/cs/analytics/CommitAnalytics.java @@ -4,6 +4,7 @@ import edu.byu.cs.canvas.CanvasIntegrationImpl; import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.SubmissionDao; import edu.byu.cs.model.Phase; import edu.byu.cs.model.Submission; @@ -70,7 +71,7 @@ private record CommitDatum( * * @return a serialized version of the data */ - public static String generateCSV() { + public static String generateCSV() throws DataAccessException { SubmissionDao submissionDao = DaoService.getSubmissionDao(); diff --git a/src/main/java/edu/byu/cs/analytics/CommitAnalyticsRouter.java b/src/main/java/edu/byu/cs/analytics/CommitAnalyticsRouter.java index 9732a44c5..15827e586 100644 --- a/src/main/java/edu/byu/cs/analytics/CommitAnalyticsRouter.java +++ b/src/main/java/edu/byu/cs/analytics/CommitAnalyticsRouter.java @@ -1,5 +1,6 @@ package edu.byu.cs.analytics; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.util.DateTimeUtils; import edu.byu.cs.util.FileUtils; @@ -18,7 +19,7 @@ public class CommitAnalyticsRouter { * * @return the CSV data */ - public static String update() { + public static String update() throws DataAccessException { long ts = Instant.now().getEpochSecond(); String data = CommitAnalytics.generateCSV(); diff --git a/src/main/java/edu/byu/cs/autograder/TrafficController.java b/src/main/java/edu/byu/cs/autograder/TrafficController.java index 6289dd818..13325487c 100644 --- a/src/main/java/edu/byu/cs/autograder/TrafficController.java +++ b/src/main/java/edu/byu/cs/autograder/TrafficController.java @@ -2,6 +2,7 @@ import edu.byu.cs.controller.WebSocketController; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.QueueItem; import org.eclipse.jetty.websocket.api.Session; @@ -38,7 +39,7 @@ public static TrafficController getInstance() { * Broadcasts the current queue status to all connected clients. * Each client will be notified of their specific position in the queue. */ - public static void broadcastQueueStatus() { + public static void broadcastQueueStatus() throws DataAccessException { List usersWaitingInQueue = new ArrayList<>(); for (QueueItem item : DaoService.getQueueDao().getAll()) diff --git a/src/main/java/edu/byu/cs/autograder/git/GitHelper.java b/src/main/java/edu/byu/cs/autograder/git/GitHelper.java index f73c6d2a2..b245998a3 100644 --- a/src/main/java/edu/byu/cs/autograder/git/GitHelper.java +++ b/src/main/java/edu/byu/cs/autograder/git/GitHelper.java @@ -4,6 +4,7 @@ import edu.byu.cs.autograder.GradingContext; import edu.byu.cs.autograder.GradingException; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.Submission; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; @@ -70,7 +71,7 @@ private int verifyRegularCommits() throws GradingException { // } return numCommits; - } catch (IOException | GitAPIException e) { + } catch (IOException | GitAPIException | DataAccessException e) { gradingContext.observer().notifyError("Failed to count commits: " + e.getMessage()); LOGGER.error("Failed to count commits", e); throw new GradingException("Failed to count commits: ", e.getMessage()); diff --git a/src/main/java/edu/byu/cs/autograder/quality/QualityGrader.java b/src/main/java/edu/byu/cs/autograder/quality/QualityGrader.java index 781c05e46..1a0de6fbe 100644 --- a/src/main/java/edu/byu/cs/autograder/quality/QualityGrader.java +++ b/src/main/java/edu/byu/cs/autograder/quality/QualityGrader.java @@ -3,6 +3,7 @@ import edu.byu.cs.autograder.GradingContext; import edu.byu.cs.autograder.GradingException; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.Rubric; import edu.byu.cs.model.RubricConfig; @@ -16,7 +17,7 @@ public class QualityGrader { * * @return the results of the quality checks as a CanvasIntegration.RubricItem */ - public Rubric.Results runQualityChecks() throws GradingException { + public Rubric.Results runQualityChecks() throws GradingException, DataAccessException { RubricConfig rubricConfig = DaoService.getRubricConfigDao().getRubricConfig(gradingContext.phase()); if(rubricConfig.quality() == null) return null; gradingContext.observer().update("Running code quality..."); diff --git a/src/main/java/edu/byu/cs/autograder/score/LateDayCalculator.java b/src/main/java/edu/byu/cs/autograder/score/LateDayCalculator.java index 2b2b2b533..45a651bf0 100644 --- a/src/main/java/edu/byu/cs/autograder/score/LateDayCalculator.java +++ b/src/main/java/edu/byu/cs/autograder/score/LateDayCalculator.java @@ -4,6 +4,7 @@ import edu.byu.cs.canvas.CanvasException; import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.Phase; import edu.byu.cs.util.PhaseUtils; import org.eclipse.jgit.annotations.NonNull; @@ -39,7 +40,7 @@ public LateDayCalculator() { initializePublicHolidays(getEncodedPublicHolidays()); } - public int calculateLateDays(Phase phase, String netId) throws GradingException { + public int calculateLateDays(Phase phase, String netId) throws GradingException, DataAccessException { int assignmentNum = PhaseUtils.getPhaseAssignmentNumber(phase); int canvasUserId = DaoService.getUserDao().getUser(netId).canvasUserId(); diff --git a/src/main/java/edu/byu/cs/autograder/score/Scorer.java b/src/main/java/edu/byu/cs/autograder/score/Scorer.java index 632062aef..8c85b4c03 100644 --- a/src/main/java/edu/byu/cs/autograder/score/Scorer.java +++ b/src/main/java/edu/byu/cs/autograder/score/Scorer.java @@ -7,6 +7,7 @@ import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.canvas.CanvasUtils; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.SubmissionDao; import edu.byu.cs.dataAccess.UserDao; import edu.byu.cs.model.*; @@ -34,7 +35,7 @@ public Scorer(GradingContext gradingContext) { this.gradingContext = gradingContext; } - public Submission score(Rubric rubric, int numCommits) throws GradingException { + public Submission score(Rubric rubric, int numCommits) throws GradingException, DataAccessException { gradingContext.observer().update("Grading..."); rubric = CanvasUtils.decimalScoreToPoints(gradingContext.phase(), rubric); @@ -137,7 +138,7 @@ private float totalPoints(CanvasIntegration.RubricAssessment assessment) { return points; } - private float calculateScoreWithLatePenalty(Rubric rubric, int numDaysLate) throws GradingException { + private float calculateScoreWithLatePenalty(Rubric rubric, int numDaysLate) throws GradingException, DataAccessException { float score = getScore(rubric); score *= 1 - (numDaysLate * PER_DAY_LATE_PENALTY); if (score < 0) score = 0; @@ -149,7 +150,7 @@ private float calculateScoreWithLatePenalty(Rubric rubric, int numDaysLate) thro * * @return the score */ - private float getScore(Rubric rubric) throws GradingException { + private float getScore(Rubric rubric) throws GradingException, DataAccessException { int totalPossiblePoints = DaoService.getRubricConfigDao().getPhaseTotalPossiblePoints(gradingContext.phase()); if (totalPossiblePoints == 0) @@ -174,7 +175,7 @@ private float getScore(Rubric rubric) throws GradingException { * @param rubric the rubric for the phase */ private Submission saveResults(Rubric rubric, int numCommits, int numDaysLate, float score, String notes) - throws GradingException { + throws GradingException, DataAccessException { String headHash = getHeadHash(); String netId = gradingContext.netId(); diff --git a/src/main/java/edu/byu/cs/autograder/test/TestGrader.java b/src/main/java/edu/byu/cs/autograder/test/TestGrader.java index ed0c5b68f..dd01718ba 100644 --- a/src/main/java/edu/byu/cs/autograder/test/TestGrader.java +++ b/src/main/java/edu/byu/cs/autograder/test/TestGrader.java @@ -3,6 +3,7 @@ import edu.byu.cs.autograder.GradingContext; import edu.byu.cs.autograder.GradingException; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.Rubric; import edu.byu.cs.model.RubricConfig; import edu.byu.cs.util.PhaseUtils; @@ -42,7 +43,7 @@ public TestGrader(GradingContext gradingContext) { } - public Rubric.Results runTests() throws GradingException { + public Rubric.Results runTests() throws GradingException, DataAccessException { compileTests(); gradingContext.observer().update("Running " + name() + " tests..."); diff --git a/src/main/java/edu/byu/cs/canvas/CanvasUtils.java b/src/main/java/edu/byu/cs/canvas/CanvasUtils.java index 359b65710..0d133bd75 100644 --- a/src/main/java/edu/byu/cs/canvas/CanvasUtils.java +++ b/src/main/java/edu/byu/cs/canvas/CanvasUtils.java @@ -2,6 +2,7 @@ import edu.byu.cs.autograder.GradingException; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.Phase; import edu.byu.cs.model.Rubric; import edu.byu.cs.model.RubricConfig; @@ -21,7 +22,7 @@ public class CanvasUtils { * @param rubric the rubric to convert * @return the rubric with the score converted to points */ - public static Rubric decimalScoreToPoints(Phase phase, Rubric rubric) throws GradingException { + public static Rubric decimalScoreToPoints(Phase phase, Rubric rubric) throws GradingException, DataAccessException { RubricConfig rubricConfig = DaoService.getRubricConfigDao().getRubricConfig(phase); Rubric.RubricItem convertedPassoffTests = null; diff --git a/src/main/java/edu/byu/cs/canvas/FakeCanvasIntegration.java b/src/main/java/edu/byu/cs/canvas/FakeCanvasIntegration.java index 3ad73e779..9f6b053f6 100644 --- a/src/main/java/edu/byu/cs/canvas/FakeCanvasIntegration.java +++ b/src/main/java/edu/byu/cs/canvas/FakeCanvasIntegration.java @@ -1,16 +1,22 @@ package edu.byu.cs.canvas; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.model.User; import java.time.ZonedDateTime; import java.util.Collection; import java.util.HashSet; -public class FakeCanvasIntegration implements CanvasIntegration{ +public class FakeCanvasIntegration implements CanvasIntegration { @Override - public User getUser(String netId) { - User user = DaoService.getUserDao().getUser(netId); + public User getUser(String netId) throws CanvasException { + User user = null; + try { + user = DaoService.getUserDao().getUser(netId); + } catch (DataAccessException e) { + throw new CanvasException("Error getting user from database", e); + } if(user == null) { user = new User(netId, 0, "FirstName", "LastName", null, User.Role.ADMIN); } diff --git a/src/main/java/edu/byu/cs/controller/AdminController.java b/src/main/java/edu/byu/cs/controller/AdminController.java index 4c33d84d2..ae4577d81 100644 --- a/src/main/java/edu/byu/cs/controller/AdminController.java +++ b/src/main/java/edu/byu/cs/controller/AdminController.java @@ -4,9 +4,11 @@ import edu.byu.cs.analytics.CommitAnalyticsRouter; import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.UserDao; import edu.byu.cs.honorChecker.HonorCheckerCompiler; import edu.byu.cs.model.User; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spark.Route; @@ -19,10 +21,20 @@ import static spark.Spark.halt; public class AdminController { + + private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class); + public static final Route usersGet = (req, res) -> { UserDao userDao = DaoService.getUserDao(); - Collection users = userDao.getUsers(); + Collection users = null; + try { + users = userDao.getUsers(); + } catch (DataAccessException e) { + LOGGER.error("Error getting users", e); + halt(500); + return null; + } res.type("application/json"); res.status(200); @@ -35,32 +47,46 @@ public class AdminController { String netId = req.params(":netId"); UserDao userDao = DaoService.getUserDao(); - User user = userDao.getUser(netId); + User user; + try { + user = userDao.getUser(netId); + } catch (DataAccessException e) { + LOGGER.error("Error getting user", e); + halt(500); + return null; + } + if (user == null) { halt(404, "user not found"); return null; } - String firstName = req.queryParams("firstName"); - if (firstName != null) - userDao.setFirstName(user.netId(), firstName); - - String lastName = req.queryParams("lastName"); - if (lastName != null) - userDao.setLastName(user.netId(), lastName); - - String repoUrl = req.queryParams("repoUrl"); - if (repoUrl != null) - userDao.setRepoUrl(user.netId(), repoUrl); - - String role = req.queryParams("role"); - if (role != null) { - try { - userDao.setRole(user.netId(), User.Role.valueOf(role.toUpperCase())); - } catch (IllegalArgumentException e) { - halt(400, "invalid role. must be one of: STUDENT, ADMIN"); - return null; + try { + String firstName = req.queryParams("firstName"); + if (firstName != null) + userDao.setFirstName(user.netId(), firstName); + + String lastName = req.queryParams("lastName"); + if (lastName != null) + userDao.setLastName(user.netId(), lastName); + + String repoUrl = req.queryParams("repoUrl"); + if (repoUrl != null) + userDao.setRepoUrl(user.netId(), repoUrl); + + String role = req.queryParams("role"); + if (role != null) { + try { + userDao.setRole(user.netId(), User.Role.valueOf(role.toUpperCase())); + } catch (IllegalArgumentException e) { + halt(400, "invalid role. must be one of: STUDENT, ADMIN"); + return null; + } } + } catch (DataAccessException e) { + LOGGER.error("Error updating user", e); + halt(500); + return null; } res.status(204); @@ -72,17 +98,38 @@ public class AdminController { User latestTestStudent = CanvasService.getCanvasIntegration().getTestStudent(); UserDao userDao = DaoService.getUserDao(); - User user = userDao.getUser("test"); + User user; + try { + user = userDao.getUser("test"); + } catch (DataAccessException e) { + LOGGER.error("Error getting user", e); + halt(500); + return null; + } - if (user == null) { - user = latestTestStudent; - userDao.insertUser(latestTestStudent); - } else { - userDao.setRepoUrl(user.netId(), latestTestStudent.repoUrl()); - userDao.setCanvasUserId(user.netId(), latestTestStudent.canvasUserId()); + try { + + if (user == null) { + user = latestTestStudent; + userDao.insertUser(latestTestStudent); + } else { + userDao.setRepoUrl(user.netId(), latestTestStudent.repoUrl()); + userDao.setCanvasUserId(user.netId(), latestTestStudent.canvasUserId()); + } + + } catch (DataAccessException e) { + LOGGER.error("Error updating user", e); + halt(500); + return null; } - DaoService.getSubmissionDao().removeSubmissionsByNetId(user.netId()); + try { + DaoService.getSubmissionDao().removeSubmissionsByNetId(user.netId()); + } catch (DataAccessException e) { + LOGGER.error("Error removing submissions", e); + halt(500); + return null; + } res.cookie("/", "token", generateToken(user.netId()), 14400, false, false); @@ -103,7 +150,7 @@ public class AdminController { default -> throw new IllegalStateException("Not found (invalid option: " + option + ")"); }; } catch (Exception e) { - LoggerFactory.getLogger(AdminController.class).error(e.getMessage()); + LOGGER.error(e.getMessage()); if (e instanceof IllegalStateException) res.status(404); else res.status(500); return e.getMessage(); @@ -139,6 +186,7 @@ public class AdminController { return res.raw(); } } catch (Exception e) { + LOGGER.error("Error compiling honor checker", e); res.status(500); return e.getMessage(); } diff --git a/src/main/java/edu/byu/cs/controller/CasController.java b/src/main/java/edu/byu/cs/controller/CasController.java index c6159c774..1f5ec06f6 100644 --- a/src/main/java/edu/byu/cs/controller/CasController.java +++ b/src/main/java/edu/byu/cs/controller/CasController.java @@ -4,6 +4,7 @@ import edu.byu.cs.canvas.CanvasException; import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.UserDao; import edu.byu.cs.model.User; import edu.byu.cs.properties.ApplicationProperties; @@ -37,7 +38,14 @@ public class CasController { UserDao userDao = DaoService.getUserDao(); - User user = userDao.getUser(netId); + User user = null; + try { + user = userDao.getUser(netId); + } catch (DataAccessException e) { + LOGGER.error("Couldn't get user from database", e); + halt(500); + return null; + } if (user == null) { try { @@ -47,7 +55,7 @@ public class CasController { String errorUrlParam = URLEncoder.encode(e.getMessage(), StandardCharsets.UTF_8); res.redirect(ApplicationProperties.frontendUrl() + "/login?error=" + errorUrlParam, 302); - halt(500, "Couldn't create user from Canvas"); + halt(500); return null; } diff --git a/src/main/java/edu/byu/cs/controller/SubmissionController.java b/src/main/java/edu/byu/cs/controller/SubmissionController.java index 2db516d24..bfadfcc57 100644 --- a/src/main/java/edu/byu/cs/controller/SubmissionController.java +++ b/src/main/java/edu/byu/cs/controller/SubmissionController.java @@ -62,7 +62,7 @@ private static Boolean getSubmissionsEnabledConfig() { Boolean.class); } catch (Exception e) { LOGGER.error("Error getting configuration", e); - halt(500, "Error getting configuration"); + halt(500); return null; } return submissionsEnabled; @@ -83,7 +83,7 @@ private static Boolean getSubmissionsEnabledConfig() { return ""; }; - private static void startGrader(String netId, Phase phase, String repoUrl, boolean adminSubmission) { + private static void startGrader(String netId, Phase phase, String repoUrl, boolean adminSubmission) throws DataAccessException { DaoService.getQueueDao().add( new edu.byu.cs.model.QueueItem( netId, @@ -104,12 +104,12 @@ private static void startGrader(String netId, Phase phase, String repoUrl, boole LOGGER.error("Invalid phase", e); halt(400, "Invalid phase"); } catch (Exception e) { - LOGGER.error("Something went wrong submitting", e); - halt(500, "Something went wrong"); + LOGGER.error("Error starting grader", e); + halt(500); } } - private static void updateRepoFromCanvas(User user, Request req) throws CanvasException { + private static void updateRepoFromCanvas(User user, Request req) throws CanvasException, DataAccessException { CanvasIntegration canvas = CanvasService.getCanvasIntegration(); String newRepoUrl = canvas.getGitRepo(user.canvasUserId()); if (!newRepoUrl.equals(user.repoUrl())) { @@ -119,7 +119,7 @@ private static void updateRepoFromCanvas(User user, Request req) throws CanvasEx } } - private static boolean verifyHasNewCommits(User user, Phase phase) { + private static boolean verifyHasNewCommits(User user, Phase phase) throws DataAccessException { String headHash; try { headHash = getRemoteHeadHash(user.repoUrl()); @@ -136,7 +136,7 @@ private static boolean verifyHasNewCommits(User user, Phase phase) { return true; } - private static GradeRequest validateAndUnpackRequest(Request req) { + private static GradeRequest validateAndUnpackRequest(Request req) throws DataAccessException { User user = req.session().attribute("user"); String netId = user.netId(); @@ -178,7 +178,7 @@ private static GradeRequest validateAndUnpackRequest(Request req) { * @param phase the phase of the project to get * @return the most recent submission, or null if there are no submissions for this student in this phase */ - public static Submission getMostRecentSubmission(String netId, Phase phase) { + public static Submission getMostRecentSubmission(String netId, Phase phase) throws DataAccessException { Collection submissions = DaoService.getSubmissionDao().getSubmissionsForPhase(netId, phase); Submission mostRecent = null; @@ -227,7 +227,13 @@ public static Submission getMostRecentSubmission(String netId, Phase phase) { public static final Route latestSubmissionsGet = (req, res) -> { String countString = req.params(":count"); int count = countString == null ? -1 : Integer.parseInt(countString); // if they don't give a count, set it to -1, which gets all latest submissions - Collection submissions = DaoService.getSubmissionDao().getAllLatestSubmissions(count); + Collection submissions = null; + try { + DaoService.getSubmissionDao().getAllLatestSubmissions(count); + } catch (DataAccessException e) { + LOGGER.error("Error getting latest submissions", e); + halt(500); + } res.status(200); res.type("application/json"); @@ -238,10 +244,15 @@ public static Submission getMostRecentSubmission(String netId, Phase phase) { }; public static final Route submissionsActiveGet = (req, res) -> { - List inQueue = DaoService.getQueueDao().getAll().stream().filter((queueItem) -> !queueItem.started()).map(QueueItem::netId).toList(); - - List currentlyGrading = DaoService.getQueueDao().getAll().stream().filter(QueueItem::started).map(QueueItem::netId).toList(); - + List inQueue = null; + List currentlyGrading = null; + try { + inQueue = DaoService.getQueueDao().getAll().stream().filter((queueItem) -> !queueItem.started()).map(QueueItem::netId).toList(); + currentlyGrading = DaoService.getQueueDao().getAll().stream().filter(QueueItem::started).map(QueueItem::netId).toList(); + } catch (DataAccessException e) { + LOGGER.error("Error getting active submissions", e); + halt(500); + } res.status(200); res.type("application/json"); @@ -256,7 +267,13 @@ public static Submission getMostRecentSubmission(String netId, Phase phase) { String netId = req.params(":netId"); SubmissionDao submissionDao = DaoService.getSubmissionDao(); - Collection submissions = submissionDao.getSubmissionsForUser(netId); + Collection submissions = null; + try { + submissions = submissionDao.getSubmissionsForUser(netId); + } catch (DataAccessException e) { + LOGGER.error("Error getting submissions for user " + netId, e); + halt(500); + } res.status(200); res.type("application/json"); @@ -279,7 +296,12 @@ private static Grader getGrader(String netId, Phase phase, String repoUrl, boole Grader.Observer observer = new Grader.Observer() { @Override public void notifyStarted() { - DaoService.getQueueDao().markStarted(netId); + try { + DaoService.getQueueDao().markStarted(netId); + } catch (DataAccessException e) { + LOGGER.error("Error marking queue item as started", e); + return; + } TrafficController.getInstance().notifySubscribers(netId, Map.of( "type", "started" @@ -318,7 +340,11 @@ public void notifyError(String message, String details) { )); TrafficController.sessions.remove(netId); - DaoService.getQueueDao().remove(netId); + try { + DaoService.getQueueDao().remove(netId); + } catch (DataAccessException e) { + LOGGER.error("Error removing queue item", e); + } } @Override @@ -336,7 +362,11 @@ public void notifyDone(Submission submission) { } TrafficController.sessions.remove(netId); - DaoService.getQueueDao().remove(netId); + try { + DaoService.getQueueDao().remove(netId); + } catch (DataAccessException e) { + LOGGER.error("Error removing queue item", e); + } } }; @@ -374,7 +404,7 @@ public static String getRemoteHeadHash(String repoUrl) { * Used if the queue got stuck or if the server crashed while submissions were * waiting in the queue. */ - public static void reRunSubmissionsInQueue() throws IOException { + public static void reRunSubmissionsInQueue() throws IOException, DataAccessException { QueueDao queueDao = DaoService.getQueueDao(); UserDao userDao = DaoService.getUserDao(); Collection inQueue = queueDao.getAll(); diff --git a/src/main/java/edu/byu/cs/controller/WebSocketController.java b/src/main/java/edu/byu/cs/controller/WebSocketController.java index 2c83fd675..1e6f755ce 100644 --- a/src/main/java/edu/byu/cs/controller/WebSocketController.java +++ b/src/main/java/edu/byu/cs/controller/WebSocketController.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import edu.byu.cs.autograder.TrafficController; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.util.JwtUtils; import org.eclipse.jetty.websocket.api.CloseException; import org.eclipse.jetty.websocket.api.Session; @@ -44,7 +45,12 @@ public void onMessage(Session session, String message) { return; TrafficController.sessions.get(netId).add(session); - TrafficController.broadcastQueueStatus(); + try { + TrafficController.broadcastQueueStatus(); + } catch (DataAccessException e) { + LOGGER.error("Error broadcasting queue status", e); + throw new RuntimeException("Error broadcasting queue status", e); + } } /** diff --git a/src/main/java/edu/byu/cs/dataAccess/ConfigurationDao.java b/src/main/java/edu/byu/cs/dataAccess/ConfigurationDao.java index b85365c79..c86bca17e 100644 --- a/src/main/java/edu/byu/cs/dataAccess/ConfigurationDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/ConfigurationDao.java @@ -3,8 +3,8 @@ import java.util.Map; public interface ConfigurationDao { - void setConfiguration(Configuration key, T value, Class type); - T getConfiguration(Configuration key, Class type); + void setConfiguration(Configuration key, T value, Class type) throws DataAccessException; + T getConfiguration(Configuration key, Class type) throws DataAccessException; enum Configuration { STUDENT_SUBMISSION_ENABLED diff --git a/src/main/java/edu/byu/cs/dataAccess/DataAccessException.java b/src/main/java/edu/byu/cs/dataAccess/DataAccessException.java index 5a1e24118..9b82b9ac2 100644 --- a/src/main/java/edu/byu/cs/dataAccess/DataAccessException.java +++ b/src/main/java/edu/byu/cs/dataAccess/DataAccessException.java @@ -3,7 +3,7 @@ /** * A generic exception for data access errors */ -public class DataAccessException extends RuntimeException { +public class DataAccessException extends Exception { public DataAccessException(String message) { super(message); } diff --git a/src/main/java/edu/byu/cs/dataAccess/QueueDao.java b/src/main/java/edu/byu/cs/dataAccess/QueueDao.java index 1cb5f436a..ad3dd52dd 100644 --- a/src/main/java/edu/byu/cs/dataAccess/QueueDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/QueueDao.java @@ -10,28 +10,28 @@ public interface QueueDao { * * @param item the item to add */ - void add(QueueItem item); + void add(QueueItem item) throws DataAccessException; /** * Removes the next item from the queue * * @return the next item in the queue */ - QueueItem pop(); + QueueItem pop() throws DataAccessException; /** * Removes an item from the queue * * @param netId the netId of the item to remove */ - void remove(String netId); + void remove(String netId) throws DataAccessException; /** * Gets all items in the queue * * @return all items in the queue */ - Collection getAll(); + Collection getAll() throws DataAccessException; /** * Gets the number of items in the queue @@ -39,16 +39,16 @@ public interface QueueDao { * @param netId the netId of the item to check * @return true if the item is in the queue, false otherwise */ - boolean isAlreadyInQueue(String netId); + boolean isAlreadyInQueue(String netId) throws DataAccessException; /** * Marks an item as being started to be graded * * @param netId the netId of the item to mark */ - void markStarted(String netId); + void markStarted(String netId) throws DataAccessException; - void markNotStarted(String netId); + void markNotStarted(String netId) throws DataAccessException; /** * Gets an item from the queue @@ -56,5 +56,5 @@ public interface QueueDao { * @param netId the netId of the item to get * @return the item with the given netId */ - QueueItem get(String netId); + QueueItem get(String netId) throws DataAccessException; } diff --git a/src/main/java/edu/byu/cs/dataAccess/RubricConfigDao.java b/src/main/java/edu/byu/cs/dataAccess/RubricConfigDao.java index ade9c4fb3..b1948de7f 100644 --- a/src/main/java/edu/byu/cs/dataAccess/RubricConfigDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/RubricConfigDao.java @@ -11,9 +11,9 @@ public interface RubricConfigDao { * @param phase the phase of the rubric * @return the rubric for the given phase */ - RubricConfig getRubricConfig(Phase phase); + RubricConfig getRubricConfig(Phase phase) throws DataAccessException; - int getPhaseTotalPossiblePoints(Phase phase); + int getPhaseTotalPossiblePoints(Phase phase) throws DataAccessException; void setRubricConfig(Phase phase, RubricConfig rubricConfig) throws DataAccessException; } diff --git a/src/main/java/edu/byu/cs/dataAccess/SubmissionDao.java b/src/main/java/edu/byu/cs/dataAccess/SubmissionDao.java index f875d1e60..5c3fc65ba 100644 --- a/src/main/java/edu/byu/cs/dataAccess/SubmissionDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/SubmissionDao.java @@ -12,7 +12,7 @@ public interface SubmissionDao { * * @param submission the submission to insert */ - void insertSubmission(Submission submission); + void insertSubmission(Submission submission) throws DataAccessException; /** * Gets all submissions for the given netId and phase @@ -21,7 +21,7 @@ public interface SubmissionDao { * @param phase the phase to get submissions for * @return all submissions for the given netId and phase */ - Collection getSubmissionsForPhase(String netId, Phase phase); + Collection getSubmissionsForPhase(String netId, Phase phase) throws DataAccessException; /** * Gets all submissions for the given netId @@ -29,14 +29,14 @@ public interface SubmissionDao { * @param netId the netId to get submissions for * @return all submissions for the given netId */ - Collection getSubmissionsForUser(String netId); + Collection getSubmissionsForUser(String netId) throws DataAccessException; /** * Gets all latest submissions * * @return all latest submissions */ - Collection getAllLatestSubmissions(); + Collection getAllLatestSubmissions() throws DataAccessException; /** * Gets the X most recent latest submissions @@ -44,7 +44,7 @@ public interface SubmissionDao { * @param batchSize defines how many submissions to return. Set batchSize to a negative int to get All submissions * @return the most recent X submissions */ - Collection getAllLatestSubmissions(int batchSize); + Collection getAllLatestSubmissions(int batchSize) throws DataAccessException; /** * Removes all submissions for the given netId @@ -52,7 +52,7 @@ public interface SubmissionDao { * * @param netId the netId to remove submissions for */ - void removeSubmissionsByNetId(String netId); + void removeSubmissionsByNetId(String netId) throws DataAccessException; /** * Gets the first passing submission chronologically for the given phase @@ -61,7 +61,7 @@ public interface SubmissionDao { * @param phase the phase * @return the submission object, or null */ - Submission getFirstPassingSubmission(String netId, Phase phase); + Submission getFirstPassingSubmission(String netId, Phase phase) throws DataAccessException; - float getBestScoreForPhase(String netId, Phase phase); + float getBestScoreForPhase(String netId, Phase phase) throws DataAccessException; } diff --git a/src/main/java/edu/byu/cs/dataAccess/UserDao.java b/src/main/java/edu/byu/cs/dataAccess/UserDao.java index 3f088c3f2..0e912c858 100644 --- a/src/main/java/edu/byu/cs/dataAccess/UserDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/UserDao.java @@ -15,7 +15,7 @@ public interface UserDao { * * @param user the user to insert */ - void insertUser(User user); + void insertUser(User user) throws DataAccessException; /** * Gets the user with the given netId @@ -23,7 +23,7 @@ public interface UserDao { * @param netId the netId of the user to get * @return the user with the given netId */ - User getUser(String netId); + User getUser(String netId) throws DataAccessException; /** * Sets the first name for the given netId @@ -31,7 +31,7 @@ public interface UserDao { * @param netId * @param firstName */ - void setFirstName(String netId, String firstName); + void setFirstName(String netId, String firstName) throws DataAccessException; /** * Sets the last name for the given netId @@ -39,7 +39,7 @@ public interface UserDao { * @param netId * @param lastName */ - void setLastName(String netId, String lastName); + void setLastName(String netId, String lastName) throws DataAccessException; /** * Sets the repoUrl for the given netId @@ -47,7 +47,7 @@ public interface UserDao { * @param netId the netId to set the repoUrl for * @param repoUrl the repoUrl to set for the given netId */ - void setRepoUrl(String netId, String repoUrl); + void setRepoUrl(String netId, String repoUrl) throws DataAccessException; /** * Sets the role for the given netId @@ -55,7 +55,7 @@ public interface UserDao { * @param netId the netId to set the role for * @param role the role to set for the given netId */ - void setRole(String netId, User.Role role); + void setRole(String netId, User.Role role) throws DataAccessException; /** * Sets the canvas user id for the given netId. @@ -64,14 +64,14 @@ public interface UserDao { * @param netId the netId to set the canvas user id for * @param canvasUserId the canvas user id to set for the given netId */ - void setCanvasUserId(String netId, int canvasUserId); + void setCanvasUserId(String netId, int canvasUserId) throws DataAccessException; /** * Gets all users * * @return all users */ - Collection getUsers(); + Collection getUsers() throws DataAccessException; /** * Checks if the given repoUrl is claimed by a user @@ -79,5 +79,5 @@ public interface UserDao { * @param repoUrl the repoUrl to check * @return true if the repoUrl is claimed by a user, false otherwise */ - boolean repoUrlClaimed(String repoUrl); + boolean repoUrlClaimed(String repoUrl) throws DataAccessException; } diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/ConfigurationSqlDao.java b/src/main/java/edu/byu/cs/dataAccess/sql/ConfigurationSqlDao.java index 486428ae2..4451a9a99 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/ConfigurationSqlDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/ConfigurationSqlDao.java @@ -16,13 +16,18 @@ public ConfigurationSqlDao() { try { getConfiguration(key, String.class); } catch (DataAccessException e) { - setConfiguration(key, DEFAULT_VALUE, String.class); + try { + setConfiguration(key, DEFAULT_VALUE, String.class); + } catch (DataAccessException ex) { + LOGGER.error("Error setting default configuration value for key: {}", key, ex); + throw new RuntimeException(ex); + } } } } @Override - public void setConfiguration(Configuration key, T value, Class type) { + public void setConfiguration(Configuration key, T value, Class type) throws DataAccessException { try (var connection = SqlDb.getConnection()) { var statement = connection.prepareStatement("INSERT INTO configuration (config_key, value) VALUES (?, ?)"); statement.setString(1, key.toString()); @@ -34,7 +39,7 @@ public void setConfiguration(Configuration key, T value, Class type) { } @Override - public T getConfiguration(Configuration key, Class type) { + public T getConfiguration(Configuration key, Class type) throws DataAccessException { try (var connection = SqlDb.getConnection(); var statement = connection.prepareStatement("SELECT value FROM configuration WHERE config_key = ?")) { statement.setString(1, key.toString()); diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/QueueSqlDao.java b/src/main/java/edu/byu/cs/dataAccess/sql/QueueSqlDao.java index 80a813dad..07f8012c0 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/QueueSqlDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/QueueSqlDao.java @@ -35,12 +35,12 @@ private static QueueItem readQueueItem(ResultSet rs) throws SQLException { "queue", COLUMN_DEFINITIONS, QueueSqlDao::readQueueItem); @Override - public void add(QueueItem item) { + public void add(QueueItem item) throws DataAccessException { sqlReader.insertItem(item); } @Override - public QueueItem pop() { + public QueueItem pop() throws DataAccessException { try (var connection = SqlDb.getConnection(); var statement = connection.prepareStatement( """ @@ -60,7 +60,7 @@ public QueueItem pop() { } @Override - public void remove(String netId) { + public void remove(String netId) throws DataAccessException { sqlReader.executeUpdate( """ DELETE FROM %s @@ -71,12 +71,12 @@ public void remove(String netId) { } @Override - public Collection getAll() { + public Collection getAll() throws DataAccessException { return sqlReader.executeQuery(""); } @Override - public boolean isAlreadyInQueue(String netId) { + public boolean isAlreadyInQueue(String netId) throws DataAccessException { var results = sqlReader.executeQuery( "WHERE net_id = ?", ps -> ps.setString(1, netId)); @@ -84,16 +84,16 @@ public boolean isAlreadyInQueue(String netId) { } @Override - public void markStarted(String netId) { + public void markStarted(String netId) throws DataAccessException { updatedStartedField(netId, true); } @Override - public void markNotStarted(String netId) { + public void markNotStarted(String netId) throws DataAccessException { updatedStartedField(netId, false); } - private void updatedStartedField(String netId, boolean started) { + private void updatedStartedField(String netId, boolean started) throws DataAccessException { sqlReader.executeUpdate( """ UPDATE %s @@ -108,7 +108,7 @@ private void updatedStartedField(String netId, boolean started) { } @Override - public QueueItem get(String netId) { + public QueueItem get(String netId) throws DataAccessException { var results = sqlReader.executeQuery( "WHERE net_id = ?", ps -> ps.setString(1, netId)); diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/RubricConfigSqlDao.java b/src/main/java/edu/byu/cs/dataAccess/sql/RubricConfigSqlDao.java index 9f6e6d147..eb7d92ff2 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/RubricConfigSqlDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/RubricConfigSqlDao.java @@ -15,7 +15,7 @@ public class RubricConfigSqlDao implements RubricConfigDao { // This file isn't heavy in SQl queries, but in the logic of joining together the results. @Override - public RubricConfig getRubricConfig(Phase phase) { + public RubricConfig getRubricConfig(Phase phase) throws DataAccessException { RubricConfig.RubricConfigItem passoffTests = getRubricItem(phase, Rubric.RubricType.PASSOFF_TESTS); RubricConfig.RubricConfigItem unitTests = getRubricItem(phase, Rubric.RubricType.UNIT_TESTS); @@ -30,7 +30,7 @@ public RubricConfig getRubricConfig(Phase phase) { } @Override - public int getPhaseTotalPossiblePoints(Phase phase) { + public int getPhaseTotalPossiblePoints(Phase phase) throws DataAccessException { RubricConfig rubricConfig = getRubricConfig(phase); int total = 0; diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/SqlDb.java b/src/main/java/edu/byu/cs/dataAccess/sql/SqlDb.java index 5f2a1c2ca..b17f52898 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/SqlDb.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/SqlDb.java @@ -24,7 +24,7 @@ public class SqlDb { private static final Logger LOGGER = LoggerFactory.getLogger(SqlDb.class); - static { + public SqlDb() throws DataAccessException { try (Connection connection = DriverManager.getConnection(CONNECTION_STRING, DB_USER, DB_PASSWORD); Statement stmt = connection.createStatement()) { stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS " + DB_NAME); @@ -107,7 +107,7 @@ PRIMARY KEY (`config_key`) } } - public static Connection getConnection() { + public static Connection getConnection() throws DataAccessException { try { Connection connection = DriverManager.getConnection(CONNECTION_STRING, DB_USER, DB_PASSWORD); connection.setCatalog(DB_NAME); diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/SubmissionSqlDao.java b/src/main/java/edu/byu/cs/dataAccess/sql/SubmissionSqlDao.java index ecc20e6b5..c1f4e0ce3 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/SubmissionSqlDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/SubmissionSqlDao.java @@ -52,11 +52,11 @@ private static Submission readSubmission(ResultSet rs) throws SQLException { "submission", COLUMN_DEFINITIONS, SubmissionSqlDao::readSubmission); @Override - public void insertSubmission(Submission submission) { + public void insertSubmission(Submission submission) throws DataAccessException { sqlReader.insertItem(submission); } @Override - public Collection getSubmissionsForPhase(String netId, Phase phase) { + public Collection getSubmissionsForPhase(String netId, Phase phase) throws DataAccessException { return sqlReader.executeQuery( "WHERE net_id = ? AND phase = ?", ps -> { @@ -67,19 +67,19 @@ public Collection getSubmissionsForPhase(String netId, Phase phase) } @Override - public Collection getSubmissionsForUser(String netId) { + public Collection getSubmissionsForUser(String netId) throws DataAccessException { return sqlReader.executeQuery( "WHERE net_id = ?", ps -> ps.setString(1, netId)); } @Override - public Collection getAllLatestSubmissions() { + public Collection getAllLatestSubmissions() throws DataAccessException { return getAllLatestSubmissions(-1); } @Override - public Collection getAllLatestSubmissions(int batchSize) { + public Collection getAllLatestSubmissions(int batchSize) throws DataAccessException { return sqlReader.executeQuery( """ WHERE timestamp IN ( @@ -98,7 +98,7 @@ SELECT MAX(timestamp) } @Override - public void removeSubmissionsByNetId(String netId) { + public void removeSubmissionsByNetId(String netId) throws DataAccessException { sqlReader.executeUpdate( """ DELETE FROM %s @@ -109,7 +109,7 @@ public void removeSubmissionsByNetId(String netId) { } @Override - public Submission getFirstPassingSubmission(String netId, Phase phase) { + public Submission getFirstPassingSubmission(String netId, Phase phase) throws DataAccessException { var submissions = sqlReader.executeQuery( """ WHERE net_id = ? AND phase = ? AND passed = 1 @@ -125,7 +125,7 @@ public Submission getFirstPassingSubmission(String netId, Phase phase) { } @Override - public float getBestScoreForPhase(String netId, Phase phase) { + public float getBestScoreForPhase(String netId, Phase phase) throws DataAccessException { return sqlReader.executeQuery( """ SELECT max(score) as highestScore diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/UserSqlDao.java b/src/main/java/edu/byu/cs/dataAccess/sql/UserSqlDao.java index dc8d4705b..f2fc1323a 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/UserSqlDao.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/UserSqlDao.java @@ -38,12 +38,12 @@ private static User readUser(ResultSet rs) throws SQLException { @Override - public void insertUser(User user) { + public void insertUser(User user) throws DataAccessException { sqlReader.insertItem(user); } @Override - public User getUser(String netId) { + public User getUser(String netId) throws DataAccessException { var results = sqlReader.executeQuery( "WHERE net_id = ?", ps -> ps.setString(1, netId)); @@ -51,31 +51,31 @@ public User getUser(String netId) { } @Override - public void setFirstName(String netId, String firstName) { + public void setFirstName(String netId, String firstName) throws DataAccessException { setFieldValue(netId, "first_name", firstName); } @Override - public void setLastName(String netId, String lastName) { + public void setLastName(String netId, String lastName) throws DataAccessException { setFieldValue(netId, "last_name", lastName); } @Override - public void setRepoUrl(String netId, String repoUrl) { + public void setRepoUrl(String netId, String repoUrl) throws DataAccessException { setFieldValue(netId, "repo_url", repoUrl); } @Override - public void setRole(String netId, User.Role role) { + public void setRole(String netId, User.Role role) throws DataAccessException { setFieldValue(netId, "role", role.toString()); } @Override - public void setCanvasUserId(String netId, int canvasUserId) { + public void setCanvasUserId(String netId, int canvasUserId) throws DataAccessException { setFieldValue(netId, "canvas_user_id", canvasUserId); } - private void setFieldValue(@NonNull String netId, @NonNull String columnName, @NonNull Object columnValue) { + private void setFieldValue(@NonNull String netId, @NonNull String columnName, @NonNull Object columnValue) throws DataAccessException { sqlReader.executeUpdate( """ UPDATE user @@ -90,12 +90,12 @@ private void setFieldValue(@NonNull String netId, @NonNull String columnName, @N } @Override - public Collection getUsers() { + public Collection getUsers() throws DataAccessException { return sqlReader.executeQuery(""); } @Override - public boolean repoUrlClaimed(String repoUrl) { + public boolean repoUrlClaimed(String repoUrl) throws DataAccessException { var results = sqlReader.executeQuery( "WHERE repo_url = ?", ps -> ps.setString(1, repoUrl)); diff --git a/src/main/java/edu/byu/cs/dataAccess/sql/helpers/SqlReader.java b/src/main/java/edu/byu/cs/dataAccess/sql/helpers/SqlReader.java index 1e13039ee..960ba0ce1 100644 --- a/src/main/java/edu/byu/cs/dataAccess/sql/helpers/SqlReader.java +++ b/src/main/java/edu/byu/cs/dataAccess/sql/helpers/SqlReader.java @@ -1,9 +1,12 @@ package edu.byu.cs.dataAccess.sql.helpers; +import edu.byu.cs.controller.SubmissionController; import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.sql.SqlDb; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.sql.*; import java.util.*; @@ -12,6 +15,9 @@ import static java.sql.Types.NULL; public class SqlReader { + + private static final Logger LOGGER = LoggerFactory.getLogger(SqlReader.class); + /** Represents the name of our SQL table */ private final String TABLE_NAME; /** Represents all the columns in the table. */ @@ -99,7 +105,7 @@ private Map prepareWildcardIndices(ColumnDefinition[] column * * @param item The item to add to the table. */ - public void insertItem(@NonNull T item) { + public void insertItem(@NonNull T item) throws DataAccessException { // CONSIDER: We could prepare the statement a single time, and avoid rebuilding it. try (var connection = getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(insertStatement) @@ -190,7 +196,7 @@ public Collection readItems( * @param additionalStatementClauses Additional query clauses narrowing the results. * @return A collection of matching items. */ - public Collection executeQuery(@Nullable String additionalStatementClauses) { + public Collection executeQuery(@Nullable String additionalStatementClauses) throws DataAccessException { return executeQuery(additionalStatementClauses, x -> {}); } @@ -212,7 +218,7 @@ public Collection executeQuery(@Nullable String additionalStatementClauses) { public Collection executeQuery( @Nullable String additionalStatementClauses, @NonNull StatementPreparer statementPreparer - ) { + ) throws DataAccessException { return doExecuteQuery( selectAllStmt(additionalStatementClauses), statementPreparer, @@ -239,7 +245,7 @@ public T1 executeQuery( @NonNull String statement, @NonNull StatementPreparer statementPreparer, @NonNull ResultSetProcessor resultSetProcessor - ) { + ) throws DataAccessException { return doExecuteQuery( statement, statementPreparer, @@ -255,7 +261,7 @@ private T1 doExecuteQuery( @NonNull String statement, @NonNull StatementPreparer statementPreparer, @NonNull StatementQueryExecutor queryExecutor - ) { + ) throws DataAccessException { try ( var connection = getConnection(); PreparedStatement ps = connection.prepareStatement(statement); @@ -263,6 +269,7 @@ private T1 doExecuteQuery( statementPreparer.prepare(ps); return queryExecutor.executeQuery(ps); } catch (Exception e) { + LOGGER.error("Error executing query: " + statement, e); throw new DataAccessException("Error executing query", e); } } @@ -280,7 +287,7 @@ private T1 doExecuteQuery( public void executeUpdate( @NonNull String statement, @Nullable StatementPreparer statementPreparer - ) { + ) throws DataAccessException { try ( var connection = getConnection(); PreparedStatement ps = connection.prepareStatement(statement) @@ -301,7 +308,7 @@ public void executeUpdate( * * @return A database connection. */ - private Connection getConnection() { + private Connection getConnection() throws DataAccessException { return SqlDb.getConnection(); } diff --git a/src/main/java/edu/byu/cs/server/Server.java b/src/main/java/edu/byu/cs/server/Server.java index 24e839a88..b1bac2386 100644 --- a/src/main/java/edu/byu/cs/server/Server.java +++ b/src/main/java/edu/byu/cs/server/Server.java @@ -3,6 +3,7 @@ import edu.byu.cs.controller.SubmissionController; import edu.byu.cs.controller.WebSocketController; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.sql.*; import edu.byu.cs.properties.ApplicationProperties; import edu.byu.cs.util.ResourceUtils; @@ -186,8 +187,8 @@ public static void main(String[] args) { try { SubmissionController.reRunSubmissionsInQueue(); - } catch (IOException e) { - throw new RuntimeException("Error rerunning submissions already in queue"); + } catch (IOException | DataAccessException e) { + LOGGER.error("Error rerunning submissions already in queue", e); } } diff --git a/src/test/java/edu/byu/cs/autograder/score/ScorerTest.java b/src/test/java/edu/byu/cs/autograder/score/ScorerTest.java index e572b8ed5..114c5dbba 100644 --- a/src/test/java/edu/byu/cs/autograder/score/ScorerTest.java +++ b/src/test/java/edu/byu/cs/autograder/score/ScorerTest.java @@ -8,6 +8,7 @@ import edu.byu.cs.canvas.CanvasService; import edu.byu.cs.canvas.FakeCanvasIntegration; import edu.byu.cs.dataAccess.DaoService; +import edu.byu.cs.dataAccess.DataAccessException; import edu.byu.cs.dataAccess.memory.*; import edu.byu.cs.model.*; import edu.byu.cs.properties.ApplicationProperties; @@ -39,7 +40,7 @@ static void setUpAll() { } @BeforeEach - void setUp() { + void setUp() throws DataAccessException { spyCanvasIntegration = Mockito.spy(new FakeCanvasIntegration()); CanvasService.setCanvasIntegration(spyCanvasIntegration); @@ -86,7 +87,7 @@ void score__fullPoints() { Submission submission = null; try { submission = scorer.score(phase0Rubric, 0); - } catch (GradingException e) { + } catch (Exception e) { fail("Unexpected exception thrown: ", e); } @@ -103,7 +104,7 @@ void score__partialPoints() { Submission submission = null; try { submission = scorer.score(phase0Rubric, 0); - } catch (GradingException e) { + } catch (Exception e) { fail("Unexpected exception thrown: ", e); } @@ -120,7 +121,7 @@ void score__extraPoints() { Submission submission = null; try { submission = scorer.score(phase0Rubric, 0); - } catch (GradingException e) { + } catch (Exception e) { fail("Unexpected exception thrown: ", e); } @@ -132,7 +133,11 @@ void score__extraPoints() { @Test void score__noPossiblePoints__error() { RubricConfig emptyRubricConfig = new RubricConfig(Phase.Phase0, null, null, null); - DaoService.getRubricConfigDao().setRubricConfig(Phase.Phase0, emptyRubricConfig); + try { + DaoService.getRubricConfigDao().setRubricConfig(Phase.Phase0, emptyRubricConfig); + } catch (DataAccessException e) { + fail("Unexpected exception thrown: ", e); + } Scorer scorer = new Scorer(gradingContext); assertThrows(GradingException.class, () -> scorer.score(getRubric(1f), 0)); @@ -146,7 +151,7 @@ void score__adminSubmission() { Submission submission = null; try { submission = scorer.score(getRubric(1f), 0); - } catch (GradingException e) { + } catch (Exception e) { fail("Unexpected exception thrown: ", e); } @@ -164,17 +169,25 @@ void score__phaseNotGradeable() { null, new RubricConfig.RubricConfigItem("testCategory", "testCriteria", 30) ); - DaoService.getRubricConfigDao().setRubricConfig(Phase.Quality, phase0RubricConfig); + try { + DaoService.getRubricConfigDao().setRubricConfig(Phase.Quality, phase0RubricConfig); + } catch (DataAccessException e) { + fail("Unexpected exception thrown: ", e); + } gradingContext = new GradingContext("testNetId", Phase.Quality, "testPhasesPath", "testStagePath", "testRepoUrl", new File(""), 10, mockObserver, false); - DaoService.getQueueDao().add(new QueueItem("testNetId", Phase.Phase0, Instant.now(), true)); + try { + DaoService.getQueueDao().add(new QueueItem("testNetId", Phase.Phase0, Instant.now(), true)); + } catch (DataAccessException e) { + fail("Unexpected exception thrown: ", e); + } Scorer scorer = new Scorer(gradingContext); Submission submission = null; try { Rubric emptyRubric = new Rubric(null, null, null, true, "testNotes"); submission = scorer.score(emptyRubric, 0); - } catch (GradingException e) { + } catch (Exception e) { fail("Unexpected exception thrown: ", e); }