diff --git a/orcid-api-common/src/main/java/org/orcid/api/common/exception/JSONInputValidator.java b/orcid-api-common/src/main/java/org/orcid/api/common/exception/JSONInputValidator.java index deae4c7b415..f47ba410bac 100644 --- a/orcid-api-common/src/main/java/org/orcid/api/common/exception/JSONInputValidator.java +++ b/orcid-api-common/src/main/java/org/orcid/api/common/exception/JSONInputValidator.java @@ -12,6 +12,7 @@ import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.orcid.core.exception.ApplicationException; import org.orcid.core.exception.InvalidJSONException; import org.slf4j.Logger; @@ -31,7 +32,6 @@ public class JSONInputValidator { static { SCHEMA_LOCATIONS = new HashMap<>(); - SCHEMA_LOCATIONS.put(org.orcid.jaxb.model.v3.release.record.Work.class, "/record_3.0/work-3.0.xsd"); SCHEMA_LOCATIONS.put(org.orcid.jaxb.model.v3.release.record.Funding.class, "/record_3.0/funding-3.0.xsd"); @@ -128,15 +128,36 @@ public void validateJSONInput(Object obj) { try { source = new JAXBSource(CONTEXTS.get(clazz), obj); - VALIDATORS.get(clazz).validate(source); + Validator validator = VALIDATORS.get(clazz); + if(validator != null) { + validator.validate(source); + } else { + LOGGER.error("Unable to find validator for class " + clazz.getName()); + Map params = new HashMap<>(); + params.put("error", "Unable to find validator for class " + clazz.getName()); + throw new InvalidJSONException(params); + } } catch (SAXException e) { Map params = new HashMap<>(); - params.put("error", e.getCause().getCause().getMessage()); + Throwable rootCause = ExceptionUtils.getRootCause(e); + if(rootCause != null) { + params.put("error", rootCause.getMessage()); + } else { + // For SAXException, the message is usually 2 levels deep + params.put("error", e.getCause().getCause().getMessage()); + } throw new InvalidJSONException(params); } catch (Exception e) { - LOGGER.error("General exception from json validator", e); - throw new ApplicationException(e); - } + LOGGER.error("Unable to find validator for class " + clazz.getName()); + Map params = new HashMap<>(); + Throwable rootCause = ExceptionUtils.getRootCause(e); + if(rootCause != null) { + params.put("error", rootCause.getMessage()); + } else { + params.put("error", e.getMessage()); + } + throw new InvalidJSONException(params); + } } public void validate2_1APIJSONInput(Object obj) { diff --git a/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidExceptionMapper.java b/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidExceptionMapper.java index 0c0621161b0..f4477a20730 100644 --- a/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidExceptionMapper.java +++ b/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidExceptionMapper.java @@ -16,6 +16,7 @@ import javax.ws.rs.ext.Provider; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException; import org.jbibtex.TokenMgrError; import org.orcid.api.common.filter.ApiVersionFilter; @@ -132,8 +133,19 @@ public Response toResponse(Throwable t) { logShortError(t, clientId); } else if (t instanceof MismatchedPutCodeException) { logShortError(t, clientId); + } else if (t instanceof WrongSourceException) { + logShortError(t, clientId); + } else if (t instanceof InvalidDisambiguatedOrgException) { + logShortError(t, clientId); + } else if (t instanceof OrcidWebhookNotFoundException) { + logShortError(t, clientId); } else { - LOGGER.error("An exception has occured processing request from client " + clientId, t); + Throwable rootCause = ExceptionUtils.getRootCause(t); + if(rootCause != null) { + LOGGER.error("An exception has occurred processing request from client " + clientId, rootCause); + } else { + LOGGER.error("An exception has occurred processing request from client " + clientId, t); + } } if (isOAuthTokenRequest()) { diff --git a/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidJacksonJaxbJsonProvider.java b/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidJacksonJaxbJsonProvider.java index 9287e7b3bb8..64aec889103 100644 --- a/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidJacksonJaxbJsonProvider.java +++ b/orcid-api-common/src/main/java/org/orcid/api/common/jaxb/OrcidJacksonJaxbJsonProvider.java @@ -70,6 +70,11 @@ public Object readFrom(Class arg0, Type arg1, Annotation[] arg2, MediaTy params.put("error", e.getMessage()); throw new InvalidJSONException(params); } + if(o == null) { + Map params = new HashMap<>(); + params.put("error", "Couldn't read object, data seems to be empty or invalid"); + throw new InvalidJSONException(params); + } if (jsonInputValidator.canValidate(o.getClass())) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); String apiVersion = (String) requestAttributes.getAttribute(ApiVersionFilter.API_VERSION_REQUEST_ATTRIBUTE_NAME, RequestAttributes.SCOPE_REQUEST); diff --git a/orcid-core/src/main/java/org/orcid/core/manager/read_only/impl/RecordManagerReadOnlyImpl.java b/orcid-core/src/main/java/org/orcid/core/manager/read_only/impl/RecordManagerReadOnlyImpl.java index d797f3f5fb0..cad178049c5 100644 --- a/orcid-core/src/main/java/org/orcid/core/manager/read_only/impl/RecordManagerReadOnlyImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/manager/read_only/impl/RecordManagerReadOnlyImpl.java @@ -117,7 +117,7 @@ private Preferences getPreferences(String orcid) { } return preferences; } catch(Exception e) { - LOGGER.error("Exception loading preferences for " + orcid, e); + LOGGER.info("Locale for user " + orcid + " is not valid for V2.0/V2.1 API"); } return null; } diff --git a/orcid-core/src/main/java/org/orcid/core/oauth/service/OrcidOauth2TokenDetailServiceImpl.java b/orcid-core/src/main/java/org/orcid/core/oauth/service/OrcidOauth2TokenDetailServiceImpl.java index ab98087e127..5b1cbc6c4cb 100644 --- a/orcid-core/src/main/java/org/orcid/core/oauth/service/OrcidOauth2TokenDetailServiceImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/oauth/service/OrcidOauth2TokenDetailServiceImpl.java @@ -8,6 +8,7 @@ import javax.annotation.Resource; import javax.persistence.NoResultException; +import org.apache.commons.lang3.StringUtils; import org.orcid.core.constants.RevokeReason; import org.orcid.core.oauth.OrcidOauth2TokenDetailService; import org.orcid.core.utils.cache.redis.RedisClient; @@ -50,6 +51,9 @@ public void setOrcidOauth2TokenDetailDao(OrcidOauth2TokenDetailDao orcidOauth2To @Override public OrcidOauth2TokenDetail findNonDisabledByTokenValue(String token) { + if(StringUtils.isBlank(token)) { + return null; + } try { return orcidOauth2TokenDetailDaoReadOnly.findNonDisabledByTokenValue(token); } catch (NoResultException e) {