Skip to content

Commit

Permalink
#1158 Provide meaningful user error messages for concurrency errors
Browse files Browse the repository at this point in the history
- Refactored NotFoundException
  • Loading branch information
MPDLTam committed Jan 9, 2020
1 parent e17e2c6 commit 2b21710
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 43 deletions.
34 changes: 31 additions & 3 deletions src/main/java/de/mpg/imeji/exceptions/NotFoundException.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,40 @@
package de.mpg.imeji.exceptions;

public class NotFoundException extends ImejiException {
import java.util.Locale;

import de.mpg.imeji.logic.config.Imeji;
import de.mpg.imeji.logic.util.ObjectHelper;

public class NotFoundException extends ImejiExceptionWithUserMessage {

private static final long serialVersionUID = -6006945139992063194L;
private String objectLabel;

public NotFoundException(String message) {
super(message, null);

public NotFoundException(String internalMessage) {
super(internalMessage, "error_resource_not_found");
// minimizeStacktrace();
}

public NotFoundException(Object objectToFind, String internalMessage) {
super(internalMessage, "error_not_found");
this.objectLabel = ObjectHelper.getGUILabel(objectToFind);
}

public NotFoundException(Object objectToFind) {
super("error_not_found");
this.objectLabel = ObjectHelper.getGUILabel(objectToFind);
}

/**
* Creates a user readable error message.
*
* @return error message
*/
@Override
public String getUserMessage(Locale locale) {
String userMessage =
Imeji.RESOURCE_BUNDLE.getLabel(this.objectLabel, locale) + " " + Imeji.RESOURCE_BUNDLE.getMessage(this.userMessageLabel, locale);
return userMessage;
}
}
37 changes: 20 additions & 17 deletions src/main/java/de/mpg/imeji/j2j/controler/ResourceController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.net.URI;
import java.util.Calendar;

import org.apache.commons.lang3.NotImplementedException;
import org.apache.jena.rdf.model.Model;

import de.mpg.imeji.exceptions.AlreadyExistsException;
Expand Down Expand Up @@ -103,12 +104,13 @@ public Object read(URI uri, Object o) throws NotFoundException {
* @return
* @throws NotFoundException
*/
public Object read(Object o) throws NotFoundException {
if (!java2rdf.exists(o)) {
throw new NotFoundException(getObjectType(J2JHelper.getId(o)) + " " + getObjectId(J2JHelper.getId(o)) + " not found!");
public Object read(Object object) throws NotFoundException {
if (!java2rdf.exists(object)) {
throw new NotFoundException(object,
getObjectType(J2JHelper.getId(object)) + " " + getObjectId(J2JHelper.getId(object)) + " not found!");
}
o = rdf2Java.loadResource(o);
return o;
object = rdf2Java.loadResource(object);
return object;
}


Expand All @@ -122,8 +124,8 @@ public Object update(Object imejiDataObject) throws NotFoundException, ReloadBef

// Check if object exists in Jena
if (!java2rdf.exists(imejiDataObject)) {
throw new NotFoundException("Error updating resource " + imejiDataObject.toString() + " with id \"" + J2JHelper.getId(imejiDataObject)
+ "\". Resource doesn't exist in model " + model.toString());
throw new NotFoundException(imejiDataObject, "Error updating resource " + imejiDataObject.toString() + " with id \""
+ J2JHelper.getId(imejiDataObject) + "\". Resource doesn't exist in model " + model.toString());
}
// Check if object in database has been changed since it was last read
checkModified(imejiDataObject);
Expand All @@ -136,14 +138,14 @@ public Object update(Object imejiDataObject) throws NotFoundException, ReloadBef
/**
* Before updating a data object in Jena, check whether the object has been altered in database
* since it was last read from there. Throw ReloadBeforeSaveException in case that resource has
* been altered.
* been altered. NotImplemented
*
* @param imejiDataObject
* @throws ReloadBeforeSaveException
* @throws UnprocessableError
* @throws NotFoundException
*/
private void checkModified(Object imejiDataObject) throws ReloadBeforeSaveException, UnprocessableError, NotFoundException {
private void checkModified(Object imejiDataObject) throws ReloadBeforeSaveException, NotFoundException {
// Throw ReloadBeforeSaveException in case that object in Jena has been modified since we last read it.
if (imejiDataObject instanceof ResourceLastModified) {
if (imejiDataObject instanceof CloneURI) {
Expand All @@ -155,11 +157,12 @@ private void checkModified(Object imejiDataObject) throws ReloadBeforeSaveExcept
throw new ReloadBeforeSaveException(currentObjectInJena);
}
} else {
throw new UnprocessableError("Could not process update request, no timestamp for data synchronization available");
throw new NotImplementedException("Could not process update request, no timestamp for data synchronization available");
}
} else {
throw new UnprocessableError("Could not process update request, interface CloneURI not implemented (but needs to be) for class "
+ imejiDataObject.getClass());
throw new NotImplementedException(
"Could not process update request, interface CloneURI not implemented (but needs to be) for class "
+ imejiDataObject.getClass());
}
}
}
Expand All @@ -171,12 +174,12 @@ private void checkModified(Object imejiDataObject) throws ReloadBeforeSaveExcept
* @param o
* @throws NotFoundException
*/
public void delete(Object o) throws NotFoundException {
if (!java2rdf.exists(o)) {
throw new NotFoundException(
"Error deleting resource " + J2JHelper.getId(o).getPath().replace("imeji/", "") + ". Resource doesn't exist! ");
public void delete(Object object) throws NotFoundException {
if (!java2rdf.exists(object)) {
throw new NotFoundException(object,
"Error deleting resource " + J2JHelper.getId(object).getPath().replace("imeji/", "") + " from Jena. Resource doesn't exist! ");
}
java2rdf.remove(o);
java2rdf.remove(object);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,14 @@ public void init() {
setType(facet.getType());
setIndex(facet.getIndex());
setObjectType(facet.getObjectType());
}
catch (final ImejiExceptionWithUserMessage exceptionWithMessage) {
String userMessage = "Unknown facet. " + exceptionWithMessage.getUserMessage(getLocale());
BeanHelper.error(userMessage);
if (exceptionWithMessage.getMessage() != null) {
LOGGER.error(exceptionWithMessage.getMessage(), exceptionWithMessage);
} else {
LOGGER.error(userMessage, exceptionWithMessage);
}
}
catch (NotFoundException e) {
LOGGER.error("Error initializing FacetBean", e);
BeanHelper.error("Unknown facet: " + facetId);
} catch (final ImejiExceptionWithUserMessage exceptionWithMessage) {
String userMessage = "Unknown facet. " + exceptionWithMessage.getUserMessage(getLocale());
BeanHelper.error(userMessage);
if (exceptionWithMessage.getMessage() != null) {
LOGGER.error(exceptionWithMessage.getMessage(), exceptionWithMessage);
} else {
LOGGER.error(userMessage, exceptionWithMessage);
}
} catch (Exception e) {
LOGGER.error("Error initializing FacetBean", e);
}
Expand All @@ -62,17 +57,15 @@ public void save() {
try {
new FacetService().update(facet, getSessionUser());
redirect(getNavigation().getApplicationUrl() + "facets");
}
catch (final ImejiExceptionWithUserMessage exceptionWithMessage) {
String userMessage = "Error saving facet. " + exceptionWithMessage.getUserMessage(getLocale());
BeanHelper.error(userMessage);
if (exceptionWithMessage.getMessage() != null) {
LOGGER.error("Error saving facet. " + exceptionWithMessage.getMessage(), exceptionWithMessage);
} else {
LOGGER.error(userMessage, exceptionWithMessage);
}
} catch (final ImejiExceptionWithUserMessage exceptionWithMessage) {
String userMessage = "Error saving facet. " + exceptionWithMessage.getUserMessage(getLocale());
BeanHelper.error(userMessage);
if (exceptionWithMessage.getMessage() != null) {
LOGGER.error("Error saving facet. " + exceptionWithMessage.getMessage(), exceptionWithMessage);
} else {
LOGGER.error(userMessage, exceptionWithMessage);
}
catch (ImejiException | IOException e) {
} catch (ImejiException | IOException e) {
LOGGER.error("Error updating Facet ", e);
BeanHelper.error("Error saving Facet", e.getMessage());
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/labels_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)

COLLECTION = Sammlung

CONTAINER_METADATA_TITLE = Titel

ContainerDiscarded = zur\u00FCckgezogen
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ error_metadata_url_empty = Die URL kann nicht leer sein

error_metadata_validation = Fehler bei der Validierung der Metadaten!

error_not_found = konnte nicht gefunden werden.

error_number_format = Ung\u00FCltiges Zahl.

error_orcid_format = Please enter 16-digit number with dashes, e.g. 0000-0000-0000-0000
Expand All @@ -259,6 +261,8 @@ error_release_withdrawn_collection = Sammlung ist zur

error_reload_page = Fehler beim neu Laden der Seite.

error_resource_not_found = Resource konnte nicht gefunden werden.

error_retrieve_selected_items = Fehler beim Abfragen der ausgew\u00E4hlten Inhalte.

error_search_distance_null = Entfernung muss eingegeben werden (z.B 1km)
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ error_metadata_url_empty = URL can not be empty

error_metadata_validation = Error during metadata validation!

error_not_found = not found.

error_number_format = Invalid Number

error_orcid_format = Please enter 16-digit number with dashes, e.g. 0000-0000-0000-0000
Expand All @@ -261,6 +263,8 @@ error_release_withdrawn_collection = Cannot release collection because collectio

error_reload_page = Error while reloading the page.

error_resource_not_found = Could not find resource.

error_retrieve_selected_items = Error while retrieving the selected items.

error_search_distance_null = Distance must be set (for instance 1km)
Expand Down

0 comments on commit 2b21710

Please sign in to comment.