Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
fix(ZNTA-1073) : create custom exceptions + handlers (#1169)
Browse files Browse the repository at this point in the history
* fix(ZNTA-1073):Fix NullPointerEx on iteration view

Throw EntityNotFoundException instead of NullPointerException when
attempt to access non-existing project through writing invalid project
slug on the iteration page

* fix(ZNTA-1073):create custom exceptions + handlers

Create ProjectNotFoundEx and VersionNotFoundEx and throw them when
trying to write invalid project or iteration slug on project view or
iteration view pages. Handle these exceptions and return warn page with
the proper warning message.

* fix(ZNTA-1073):change the structure of the ex.s

Instead of passing parameters on the warning page for the error messages,
creating constructors with slug arguments and passing project slug and
version slug parameters when throwing the exceptions. Also, rename warn
page to missing_entity.

* fix(ZNTA-1073) : Add header comment

* fix(ZNTA-1073) : remove unnecessary comment

* fix(ZNTA-1073): change the exception message
  • Loading branch information
arm authored and djansen-redhat committed Jun 2, 2016
1 parent 90af336 commit 62148e1
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 4 deletions.
Expand Up @@ -4,6 +4,7 @@
import java.util.Collections;
import java.util.List;

import javax.annotation.Nullable;
import javax.faces.application.FacesMessage;

import com.google.common.collect.Lists;
Expand Down Expand Up @@ -112,7 +113,7 @@ public void setSourceProjectSlug(String sourceProjectSlug) {
this.sourceProjectSlug = sourceProjectSlug;
refreshSourceProject();
this.sourceVersionSlug = null;
if (!getSourceProject().getProjectIterations().isEmpty()) {
if (getSourceProject() != null && !getSourceProject().getProjectIterations().isEmpty()) {
this.sourceVersionSlug =
getSourceProject().getProjectIterations().get(0).getSlug();
}
Expand All @@ -133,7 +134,7 @@ public HProjectIteration getTargetVersion() {
return targetVersion;
}

public HProject getSourceProject() {
public @Nullable HProject getSourceProject() {
if(sourceProject == null && StringUtils.isNotEmpty(sourceProjectSlug)) {
sourceProject = projectDAO.getBySlug(sourceProjectSlug);
}
Expand Down
3 changes: 2 additions & 1 deletion zanata-war/src/main/java/org/zanata/action/ProjectHome.java
Expand Up @@ -62,6 +62,7 @@
import org.zanata.dao.LocaleDAO;
import org.zanata.dao.PersonDAO;
import org.zanata.dao.WebHookDAO;
import org.zanata.exception.ProjectNotFoundException;
import org.zanata.i18n.Messages;
import org.zanata.model.HAccount;
import org.zanata.model.HAccountRole;
Expand Down Expand Up @@ -691,7 +692,7 @@ private void validateProjectState(HProject project) {
log.warn(
"Project [id={}, slug={}], does not exist or is soft deleted: {}",
projectId, getSlug(), project);
throw new EntityNotFoundException();
throw new ProjectNotFoundException(getSlug());
}
}

Expand Down
16 changes: 15 additions & 1 deletion zanata-war/src/main/java/org/zanata/action/VersionHome.java
Expand Up @@ -53,6 +53,8 @@
import org.zanata.dao.ProjectDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.dao.LocaleDAO;
import org.zanata.exception.ProjectNotFoundException;
import org.zanata.exception.VersionNotFoundException;
import org.zanata.i18n.Messages;
import org.zanata.model.HLocale;
import org.zanata.model.HProject;
Expand Down Expand Up @@ -261,6 +263,9 @@ public class VersionItem implements Serializable {
@Override
protected HProjectIteration loadInstance() {
Session session = (Session) getEntityManager().getDelegate();
HProject project = (HProject) session.byNaturalId(HProject.class)
.using("slug", getProjectSlug()).load();
validateProjectState(project);
if (versionId == null) {
HProjectIteration iteration = (HProjectIteration) session
.byNaturalId(HProjectIteration.class)
Expand All @@ -284,7 +289,16 @@ private void validateIterationState(HProjectIteration iteration) {
log.warn(
"Project version [id={}, slug={}], does not exist or is soft deleted: {}",
versionId, getSlug(), iteration);
throw new EntityNotFoundException();
throw new VersionNotFoundException(getProjectSlug(), getSlug());
}
}

private void validateProjectState(HProject project) {
if (project == null || project.getStatus() == EntityStatus.OBSOLETE) {
log.warn(
"Project [slug={}], does not exist or is soft deleted: {}",
getProjectSlug(), project);
throw new ProjectNotFoundException(getProjectSlug());
}
}

Expand Down
@@ -0,0 +1,34 @@
/*
* Copyright 2016, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.exception;

public class ProjectNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final String projectSlug;

public ProjectNotFoundException(String projectSlug) {
this.projectSlug = projectSlug;
}

public String getProjectSlug() {
return projectSlug;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2016, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.exception;

public class VersionNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final String projectSlug;
private final String versionSlug;

public VersionNotFoundException(String projectSlug, String versionSlug) {
this.projectSlug = projectSlug;
this.versionSlug = versionSlug;
}

public String getProjectSlug() {
return projectSlug;
}

public String getVersionSlug() {
return versionSlug;
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2016, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

package org.zanata.exception.handler;

import org.apache.deltaspike.core.api.exception.control.ExceptionHandler;
import org.apache.deltaspike.core.api.exception.control.Handles;
import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent;
import org.zanata.exception.ProjectNotFoundException;

import javax.faces.application.FacesMessage;


@ExceptionHandler
public class ProjectNotFoundExceptionHandler extends AbstractExceptionHandler {
public void handleException(@Handles ExceptionEvent<ProjectNotFoundException> event) {
handle(event, LogLevel.Warn, urlUtil.missingEntityPage(), FacesMessage.SEVERITY_WARN,
"jsf.ProjectNotFound", event.getException().getProjectSlug());
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2016, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

package org.zanata.exception.handler;

import org.apache.deltaspike.core.api.exception.control.ExceptionHandler;
import org.apache.deltaspike.core.api.exception.control.Handles;
import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent;
import org.zanata.exception.VersionNotFoundException;

import javax.faces.application.FacesMessage;


@ExceptionHandler
public class VersionNotFoundExceptionHandler extends AbstractExceptionHandler {
public void handleException(@Handles ExceptionEvent<VersionNotFoundException> event) {
VersionNotFoundException exception = event.getException();
handle(event, LogLevel.Warn, urlUtil.missingEntityPage(), FacesMessage.SEVERITY_WARN,
"jsf.VersionNotFound", exception.getProjectSlug(), exception.getVersionSlug());
}
}
7 changes: 7 additions & 0 deletions zanata-war/src/main/java/org/zanata/util/UrlUtil.java
Expand Up @@ -286,6 +286,13 @@ public String genericErrorPage() {
return contextPath + "/error" + dswidQuery;
}

/**
* Get missing entity page url with dswid parameter
*/
public String missingEntityPage() {
return contextPath + "/error/missing_entity" + dswidQuery;
}

/**
* Get view expired url with dswid parameter
*/
Expand Down
2 changes: 2 additions & 0 deletions zanata-war/src/main/resources/messages.properties
Expand Up @@ -14,6 +14,8 @@ jsf.Deleted=Deleted
! this is shown when trying to access a project, version or other item that does not exist in the system.
! e.g. navigate to a project, then change the project slug in the URL to make it invalid and press enter.
jsf.RecordNotFound=Record not found
jsf.ProjectNotFound = Project "{0}" not found
jsf.VersionNotFound = Version "{1}" for project "{0}" not found
jsf.DuplicatedRecord=Duplicated record
jsf.AnotherUserChangedTheSameDataPleaseTryAgain=Another user changed the same data. Please try again.
jsf.YouDoNotHavePermissionToAccessThisResource=You do not have permission to access this resource.
Expand Down
43 changes: 43 additions & 0 deletions zanata-war/src/main/webapp/error/missing_entity.xhtml
@@ -0,0 +1,43 @@
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
template="../WEB-INF/template/template.xhtml">

<ui:define name="page_title">#{msgs['jsf.Error']}</ui:define>
<ui:param name="showGlobalMessages" value="false"/>
<ui:define name="center_content">
<ui:remove>
<!-- TODO [CDI] use h:messages instead of jsfMessages.globalMessagesList? -->
</ui:remove>
<ui:fragment
rendered="#{empty jsfMessages.globalMessagesList}">
<h2>#{msgs['jsf.NoErrors']}</h2>
</ui:fragment>

<ui:fragment
rendered="#{not empty jsfMessages.globalMessagesList}">
<ul class="list--no-bullets">
<li>
<div class="alert--danger">
<h2 class="alert__heading">#{msgs['jsf.ErrorTitle']}</h2>

<div class="alert__content">
<ul class="list--no-bullets">
<ui:repeat
value="#{jsfMessages.globalMessagesList}"
var="message">
<h:outputText
value="#{message.detail}">
</h:outputText>

</ui:repeat>
</ul>
</div>
</div>
</li>
</ul>
</ui:fragment>
</ui:define>
</ui:composition>

0 comments on commit 62148e1

Please sign in to comment.