diff --git a/dspace-api/src/main/java/org/dspace/core/Context.java b/dspace-api/src/main/java/org/dspace/core/Context.java index 5b0ac9b2bb67..24a1cd17f263 100644 --- a/dspace-api/src/main/java/org/dspace/core/Context.java +++ b/dspace-api/src/main/java/org/dspace/core/Context.java @@ -169,36 +169,40 @@ public Context(Mode mode) { * Initializes a new context object. */ protected void init() { - log.info("Initializing new context, mode: {}", mode); - updateDatabase(); + try { + log.info("Initializing new context, mode: {}", mode); + updateDatabase(); - if (eventService == null) { - eventService = EventServiceFactory.getInstance().getEventService(); - } - if (dbConnection == null) { - // Obtain a non-auto-committing connection - dbConnection = new DSpace().getServiceManager() - .getServiceByName(null, DBConnection.class); + if (eventService == null) { + eventService = EventServiceFactory.getInstance().getEventService(); + } if (dbConnection == null) { - log.fatal("Cannot obtain the bean which provides a database connection. " + - "Check previous entries in the dspace.log to find why the db failed to initialize."); + // Obtain a non-auto-committing connection + dbConnection = new DSpace().getServiceManager() + .getServiceByName(null, DBConnection.class); + if (dbConnection == null) { + log.fatal("Cannot obtain the bean which provides a database connection. " + + "Check previous entries in the dspace.log to find why the db failed to initialize."); + } } - } - currentUser = null; - currentLocale = I18nUtil.getDefaultLocale(); - extraLogInfo = ""; - ignoreAuth = false; + currentUser = null; + currentLocale = I18nUtil.getDefaultLocale(); + extraLogInfo = ""; + ignoreAuth = false; - specialGroups = new HashSet<>(); + specialGroups = new HashSet<>(); - authStateChangeHistory = new ConcurrentLinkedDeque<>(); - authStateClassCallHistory = new ConcurrentLinkedDeque<>(); + authStateChangeHistory = new ConcurrentLinkedDeque<>(); + authStateClassCallHistory = new ConcurrentLinkedDeque<>(); - if (this.mode != null) { - setMode(this.mode); + if (this.mode != null) { + setMode(this.mode); + } + } catch (Exception e) { + log.error("Error initializing Context", e); + throw e; // Fail fast if initialization cannot be completed } - } /** @@ -401,19 +405,23 @@ public void complete() throws SQLException { } try { - // As long as we have a valid, writeable database connection, - // commit changes. Otherwise, we'll just close the DB connection (see below) if (!isReadOnly()) { - commit(); + commit(); // Commit the transaction } + } catch (Exception e) { + log.error("Error committing transaction in complete()", e); + throw e; // Rethrow to signal failure to higher-level logic } finally { log.info("Going to close a connection."); if (dbConnection != null) { - log.info("Closing connection."); - // Free the DB connection and invalidate the Context - dbConnection.closeDBConnection(); - log.info("Connection closed."); - dbConnection = null; + try { + log.info("Closing connection."); + dbConnection.closeDBConnection(); + log.info("Connection closed."); + dbConnection = null; + } catch (SQLException ex) { + log.error("Error closing the database connection after complete()", ex); + } } } } @@ -573,8 +581,11 @@ public void rollback() throws SQLException { dbConnection.rollback(); reloadContextBoundEntities(); } + } catch (SQLException e) { + log.error("Error rolling back transaction", e); + throw e; // Signal failure to the caller } finally { - events = null; + events = null; // Clear events } } @@ -600,6 +611,7 @@ public void abort() { // Rollback ONLY if we have a database transaction, and it is NOT Read Only if (!isReadOnly() && isTransactionAlive()) { dbConnection.rollback(); + log.info("Transaction successfully rolled back during abort()."); } } catch (SQLException se) { log.error("Error rolling back transaction during an abort()", se); @@ -610,13 +622,13 @@ public void abort() { log.info("Closing connection."); // Free the DB connection & invalidate the Context dbConnection.closeDBConnection(); - log.info("Connection closed."); + log.info("Database connection closed during abort()."); dbConnection = null; } } catch (Exception ex) { - log.error("Error closing the database connection", ex); + log.error("Error closing the database connection during abort()", ex); } - events = null; + events = null; // Clear events to release resources } } @@ -626,8 +638,12 @@ public void abort() { */ @Override public void close() { - if (isValid()) { - abort(); + try { + if (isValid()) { + abort(); + } + } catch (Exception e) { + log.error("Error during context closure", e); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index 8640f64a7f8d..fb5898a6535c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -121,6 +121,7 @@ protected void handleSQLException(HttpServletRequest request, HttpServletRespons @ExceptionHandler(IOException.class) protected void handleIOException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { + log.error("Custom log: An internal read or write operation failed", ex); sendErrorResponse(request, response, ex, "An internal read or write operation failed", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);