mirror of
https://gitee.com/jmix/cuba.git
synced 2024-11-30 18:27:56 +08:00
Refs #1004 Rework remote exception handling
This commit is contained in:
parent
2981589a05
commit
3e0ba255e9
@ -10,6 +10,7 @@
|
||||
*/
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import com.haulmont.cuba.core.global.RemoteException;
|
||||
import com.haulmont.cuba.core.global.UserSessionSource;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import org.apache.commons.logging.Log;
|
||||
@ -36,16 +37,17 @@ public class ServiceInterceptor
|
||||
}
|
||||
}
|
||||
|
||||
UserSession userSession = userSessionSource.getUserSession();
|
||||
if (log.isTraceEnabled())
|
||||
log.trace("Invoking: " + ctx.getSignature() + ", session=" + userSession);
|
||||
|
||||
try {
|
||||
UserSession userSession = userSessionSource.getUserSession();
|
||||
if (log.isTraceEnabled())
|
||||
log.trace("Invoking: " + ctx.getSignature() + ", session=" + userSession);
|
||||
|
||||
Object res = ctx.proceed();
|
||||
return res;
|
||||
} catch (Throwable e) {
|
||||
log.error("ServiceInterceptor caught exception: ", e);
|
||||
throw e;
|
||||
// Propagate the special exception to avoid serialization errors on remote clients
|
||||
throw new RemoteException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,6 @@ public class App implements ConnectionListener {
|
||||
|
||||
private DisabledGlassPane glassPane;
|
||||
|
||||
protected ExceptionHandlers exceptionHandlers;
|
||||
|
||||
protected DesktopTheme theme;
|
||||
|
||||
public static void main(final String[] args) {
|
||||
@ -360,8 +358,6 @@ public class App implements ConnectionListener {
|
||||
}
|
||||
|
||||
protected void initExceptionHandling() {
|
||||
exceptionHandlers = new ExceptionHandlers();
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
public void uncaughtException(Thread thread, Throwable throwable) {
|
||||
handleException(thread, throwable);
|
||||
@ -373,25 +369,21 @@ public class App implements ConnectionListener {
|
||||
|
||||
public void handleException(Thread thread, Throwable throwable) {
|
||||
log.error("Exception in thread " + thread, throwable);
|
||||
exceptionHandlers.handle(thread, throwable);
|
||||
ExceptionHandlers handlers = AppContext.getBean("cuba_ExceptionHandlers", ExceptionHandlers.class);
|
||||
handlers.handle(thread, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes exception handlers immediately after login and logout.
|
||||
* Can be overridden in descendants to manipulate exception handlers programmatically.
|
||||
* @param isConnected true after login, false after logout
|
||||
*/
|
||||
protected void initExceptionHandlers(boolean isConnected) {
|
||||
ExceptionHandlers handlers = AppContext.getBean("cuba_ExceptionHandlers", ExceptionHandlers.class);
|
||||
if (isConnected) {
|
||||
exceptionHandlers.addHandler(new NoUserSessionHandler()); // must be the first handler
|
||||
exceptionHandlers.addHandler(new SilentExceptionHandler());
|
||||
exceptionHandlers.addHandler(new UniqueConstraintViolationHandler());
|
||||
exceptionHandlers.addHandler(new AccessDeniedHandler());
|
||||
exceptionHandlers.addHandler(new NoSuchScreenHandler());
|
||||
exceptionHandlers.addHandler(new DeletePolicyHandler());
|
||||
exceptionHandlers.addHandler(new NumericOverflowExceptionHandler());
|
||||
exceptionHandlers.addHandler(new OptimisticExceptionHandler());
|
||||
exceptionHandlers.addHandler(new JPAOptimisticExceptionHandler());
|
||||
exceptionHandlers.addHandler(new ReportExceptionHandler());
|
||||
exceptionHandlers.addHandler(new FileMissingExceptionHandler());
|
||||
exceptionHandlers.addHandler(new EntityDeletedExceptionHandler());
|
||||
handlers.createByConfiguration();
|
||||
} else {
|
||||
exceptionHandlers.getHandlers().clear();
|
||||
handlers.removeAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,36 +7,59 @@
|
||||
package com.haulmont.cuba.desktop.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.core.global.RemoteException;
|
||||
import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.AppConfig;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for exception handlers determining their ability to handle an exception by its class name.
|
||||
*
|
||||
* <p>If you need to handle a specific exception, create a descendant of this class,
|
||||
* pass handling exception class names into constructor, implement
|
||||
* {@link #doHandle(Thread, String, String, Throwable)} method
|
||||
* and register the new handler in the definition of {@link ExceptionHandlersConfiguration} bean in the client's
|
||||
* spring.xml.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public abstract class AbstractExceptionHandler<T extends Throwable> implements ExceptionHandler {
|
||||
public abstract class AbstractExceptionHandler implements ExceptionHandler {
|
||||
|
||||
private final Class<T> tClass;
|
||||
private List<String> classNames;
|
||||
|
||||
public AbstractExceptionHandler(Class<T> tClass) {
|
||||
this.tClass = tClass;
|
||||
protected AbstractExceptionHandler(String... classNames) {
|
||||
this.classNames = Arrays.asList(classNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean handle(Thread thread, Throwable exception) {
|
||||
Throwable t = exception;
|
||||
while (t != null) {
|
||||
if (tClass.isAssignableFrom(t.getClass())) {
|
||||
doHandle(thread, (T) t);
|
||||
List<Throwable> list = ExceptionUtils.getThrowableList(exception);
|
||||
for (Throwable throwable : list) {
|
||||
if (classNames.contains(throwable.getClass().getName())) {
|
||||
doHandle(thread, throwable.getClass().getName(), throwable.getMessage(), throwable);
|
||||
return true;
|
||||
}
|
||||
t = t.getCause();
|
||||
if (throwable instanceof RemoteException) {
|
||||
RemoteException remoteException = (RemoteException) throwable;
|
||||
for (RemoteException.Cause cause : remoteException.getCauses()) {
|
||||
if (classNames.contains(cause.getClassName())) {
|
||||
doHandle(thread, cause.getClassName(), cause.getMessage(), cause.getThrowable());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void doHandle(Thread thread, T t);
|
||||
protected abstract void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable);
|
||||
|
||||
protected String getMessage(String key) {
|
||||
return MessageProvider.getMessage(AppConfig.getMessagesPack(), key, App.getInstance().getLocale());
|
||||
|
@ -11,18 +11,23 @@ import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link AccessDeniedException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
*/
|
||||
public class AccessDeniedHandler extends AbstractExceptionHandler<AccessDeniedException> {
|
||||
public class AccessDeniedHandler extends AbstractExceptionHandler {
|
||||
|
||||
public AccessDeniedHandler() {
|
||||
super(AccessDeniedException.class);
|
||||
super(AccessDeniedException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, AccessDeniedException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "accessDenied.message");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Handles {@link DeletePolicyException}. Determines the exception type by searching a special marker string in the
|
||||
* messages of all exceptions in the chain.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
@ -28,8 +31,8 @@ public class DeletePolicyHandler implements ExceptionHandler {
|
||||
Throwable t = exception;
|
||||
try {
|
||||
while (t != null) {
|
||||
if (t.getMessage() != null && t.getMessage().contains(getMarker())) {
|
||||
doHandle(thread, t.getMessage());
|
||||
if (t.toString().contains(getMarker())) {
|
||||
doHandle(thread, t.toString());
|
||||
return true;
|
||||
}
|
||||
t = t.getCause();
|
||||
|
@ -11,18 +11,23 @@ import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link EntityDeletedException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author pavlov
|
||||
*/
|
||||
public class EntityDeletedExceptionHandler extends AbstractExceptionHandler<EntityDeletedException>{
|
||||
public class EntityDeletedExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public EntityDeletedExceptionHandler() {
|
||||
super(EntityDeletedException.class);
|
||||
super(EntityDeletedException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, EntityDeletedException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.formatMessage(getClass(), "entityDeletedException.message");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.WARNING);
|
||||
}
|
||||
|
@ -6,25 +6,43 @@
|
||||
|
||||
package com.haulmont.cuba.desktop.exception;
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.annotation.ManagedBean;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class that holds the collection of exception handlers and delegates unhandled exception processing to them. Handlers
|
||||
* form the chain of responsibility.
|
||||
*
|
||||
* <p>A set of exception handlers is configured by defining <code>ExceptionHandlersConfiguration</code> beans
|
||||
* in spring.xml. If a project needs specific handlers, it should define a bean of such type with its own
|
||||
* <strong>id</strong>, e.g. <code>refapp_ExceptionHandlersConfiguration</code></p>
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
@ManagedBean("cuba_ExceptionHandlers")
|
||||
public class ExceptionHandlers {
|
||||
|
||||
private LinkedList<ExceptionHandler> handlers = new LinkedList<ExceptionHandler>();
|
||||
protected LinkedList<ExceptionHandler> handlers = new LinkedList<ExceptionHandler>();
|
||||
|
||||
private ExceptionHandler defaultHandler;
|
||||
protected ExceptionHandler defaultHandler;
|
||||
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
|
||||
public ExceptionHandlers() {
|
||||
this.defaultHandler = new DefaultExceptionHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new handler if it is not yet registered
|
||||
* Adds new handler if it is not yet registered.
|
||||
* @param handler handler instance
|
||||
*/
|
||||
public void addHandler(ExceptionHandler handler) {
|
||||
if (!handlers.contains(handler))
|
||||
@ -32,14 +50,17 @@ public class ExceptionHandlers {
|
||||
}
|
||||
|
||||
/**
|
||||
* All registered handlers
|
||||
* Return all registered handlers.
|
||||
* @return modifiable handlers list
|
||||
*/
|
||||
public LinkedList<ExceptionHandler> getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates exception handling to registered handlers
|
||||
* Delegates exception handling to registered handlers.
|
||||
* @param thread current thread
|
||||
* @param exception exception instance
|
||||
*/
|
||||
public void handle(Thread thread, Throwable exception) {
|
||||
for (ExceptionHandler handler : handlers) {
|
||||
@ -48,4 +69,27 @@ public class ExceptionHandlers {
|
||||
}
|
||||
defaultHandler.handle(thread, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all handlers defined by <code>ExceptionHandlersConfiguration</code> beans in spring.xml.
|
||||
*/
|
||||
public void createByConfiguration() {
|
||||
Map<String, ExceptionHandlersConfiguration> map = AppContext.getBeansOfType(ExceptionHandlersConfiguration.class);
|
||||
for (ExceptionHandlersConfiguration conf : map.values()) {
|
||||
for (Class aClass : conf.getHandlerClasses()) {
|
||||
try {
|
||||
handlers.add(ReflectionHelper.<ExceptionHandler>newInstance(aClass));
|
||||
} catch (NoSuchMethodException e) {
|
||||
log.error("Unable to instantiate " + aClass, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all handlers.
|
||||
*/
|
||||
public void removeAll() {
|
||||
handlers.clear();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.desktop.exception;
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that is used to configure {@link ExceptionHandlers} via spring.xml.
|
||||
*
|
||||
* <p>If a project needs specific exception handlers, it should define a bean of this type with its own
|
||||
* <strong>id</strong>, e.g. <code>refapp_ExceptionHandlersConfiguration</code>, and set the list of handler class
|
||||
* names in <code>handlerClasses</code> property.</p>
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class ExceptionHandlersConfiguration {
|
||||
|
||||
private List<Class> handlerClasses = new ArrayList<Class>();
|
||||
|
||||
/**
|
||||
* Set the list of exception handler class names, usually from spring.xml.
|
||||
* @param list list of class names
|
||||
*/
|
||||
public void setHandlerClasses(List<String> list) {
|
||||
for (String className : list) {
|
||||
handlerClasses.add(ReflectionHelper.getClass(className));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of exception handler class names.
|
||||
* @return list of class names
|
||||
*/
|
||||
public List<Class> getHandlerClasses() {
|
||||
return handlerClasses;
|
||||
}
|
||||
}
|
@ -11,19 +11,25 @@ import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
import com.haulmont.cuba.gui.export.FileMissingException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link FileMissingException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author artamonov
|
||||
*/
|
||||
public class FileMissingExceptionHandler extends AbstractExceptionHandler<FileMissingException> {
|
||||
public class FileMissingExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public FileMissingExceptionHandler() {
|
||||
super(FileMissingException.class);
|
||||
super(FileMissingException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, FileMissingException e) {
|
||||
String msg = MessageProvider.formatMessage(getClass(), "fileNotFoundWarning.message", e.getFileName());
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
String fileName = throwable != null ? ((FileMissingException) throwable).getFileName() : "?";
|
||||
String msg = MessageProvider.formatMessage(getClass(), "fileNotFoundWarning.message", fileName);
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.desktop.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author artamonov
|
||||
*/
|
||||
public class JPAOptimisticExceptionHandler extends AbstractExceptionHandler<OptimisticLockException> {
|
||||
|
||||
public JPAOptimisticExceptionHandler() {
|
||||
super(OptimisticLockException.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, OptimisticLockException e) {
|
||||
Pattern pattern = Pattern.compile("\\[([^-]*)-");
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
String entityClassName = "";
|
||||
if (matcher.find()) {
|
||||
entityClassName = matcher.group(1);
|
||||
}
|
||||
|
||||
String localizedEntityName;
|
||||
String entityName = entityClassName.substring(entityClassName.lastIndexOf(".") + 1);
|
||||
String packageName = entityClassName.substring(0, entityClassName.lastIndexOf("."));
|
||||
localizedEntityName = MessageProvider.getMessage(packageName, entityName);
|
||||
|
||||
String msg = MessageProvider.formatMessage(getClass(), "optimisticException.message", "\"" + localizedEntityName + "\"");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
}
|
||||
}
|
@ -11,19 +11,23 @@ import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.NoSuchScreenException;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link NoSuchScreenException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
*/
|
||||
public class NoSuchScreenHandler extends AbstractExceptionHandler<NoSuchScreenException> {
|
||||
public class NoSuchScreenHandler extends AbstractExceptionHandler {
|
||||
|
||||
public NoSuchScreenHandler() {
|
||||
super(NoSuchScreenException.class);
|
||||
super(NoSuchScreenException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, NoSuchScreenException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "noSuchScreen.message");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
}
|
||||
|
@ -12,21 +12,25 @@ import com.haulmont.cuba.security.global.NoUserSessionException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link NoUserSessionException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class NoUserSessionHandler extends AbstractExceptionHandler<NoUserSessionException> {
|
||||
public class NoUserSessionHandler extends AbstractExceptionHandler {
|
||||
|
||||
private static Log log = LogFactory.getLog(NoUserSessionHandler.class);
|
||||
|
||||
public NoUserSessionHandler() {
|
||||
super(NoUserSessionException.class);
|
||||
super(NoUserSessionException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, NoUserSessionException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
try {
|
||||
App.getInstance().getWindowManager().showOptionDialog(
|
||||
getMessage("dialogs.Information"),
|
||||
|
@ -12,20 +12,24 @@ import com.haulmont.cuba.gui.components.IFrame;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.openjpa.lib.jdbc.ReportingSQLException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles database "numeric overflow" exception.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
*/
|
||||
public class NumericOverflowExceptionHandler extends AbstractExceptionHandler<ReportingSQLException> {
|
||||
public class NumericOverflowExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public NumericOverflowExceptionHandler() {
|
||||
super(ReportingSQLException.class);
|
||||
super(ReportingSQLException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, ReportingSQLException e) {
|
||||
if (StringUtils.containsIgnoreCase(e.getMessage(), MessageProvider.getMessage(getClass(), "numericFieldOverflow.marker"))) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
if (StringUtils.containsIgnoreCase(message, "Numeric field overflow")) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "numericFieldOverflow.message");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
}
|
||||
|
@ -9,34 +9,37 @@ package com.haulmont.cuba.desktop.exception;
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
import org.apache.openjpa.util.OptimisticException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Handles a JPA optimistic lock exception.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author artamonov
|
||||
*/
|
||||
public class OptimisticExceptionHandler extends AbstractExceptionHandler<OptimisticException> {
|
||||
public class OptimisticExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public OptimisticExceptionHandler() {
|
||||
super(OptimisticException.class);
|
||||
super("org.springframework.orm.jpa.JpaOptimisticLockingFailureException");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, OptimisticException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
Pattern pattern = Pattern.compile("\\[([^-]*)-");
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
String entityClassName = "";
|
||||
if (matcher.find()) {
|
||||
entityClassName = matcher.group(1);
|
||||
}
|
||||
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
String localizedEntityName;
|
||||
String entityName = entityClassName.substring(entityClassName.lastIndexOf(".") + 1);
|
||||
String packageName = entityClassName.substring(0, entityClassName.lastIndexOf("."));
|
||||
localizedEntityName = MessageProvider.getMessage(packageName, entityName);
|
||||
if (matcher.find()) {
|
||||
String entityClassName = matcher.group(1);
|
||||
String entityName = entityClassName.substring(entityClassName.lastIndexOf(".") + 1);
|
||||
String packageName = entityClassName.substring(0, entityClassName.lastIndexOf("."));
|
||||
localizedEntityName = MessageProvider.getMessage(packageName, entityName);
|
||||
} else {
|
||||
localizedEntityName = "?";
|
||||
}
|
||||
|
||||
String msg = MessageProvider.formatMessage(getClass(), "optimisticException.message", "\"" + localizedEntityName + "\"");
|
||||
App.getInstance().showNotificationPopup(msg, IFrame.NotificationType.ERROR);
|
||||
|
@ -13,23 +13,31 @@ import com.haulmont.cuba.report.exception.FailedToConnectToOpenOfficeException;
|
||||
import com.haulmont.cuba.report.exception.ReportingException;
|
||||
import com.haulmont.cuba.report.exception.UnsupportedFormatException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles reporting exceptions.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
*/
|
||||
public class ReportExceptionHandler extends AbstractExceptionHandler<ReportingException> {
|
||||
public class ReportExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public ReportExceptionHandler() {
|
||||
super(ReportingException.class);
|
||||
super(
|
||||
ReportingException.class.getName(),
|
||||
FailedToConnectToOpenOfficeException.class.getName(),
|
||||
UnsupportedFormatException.class.getName()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, ReportingException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
String messageCode = "reportException.message";
|
||||
if (e instanceof FailedToConnectToOpenOfficeException) {
|
||||
if (FailedToConnectToOpenOfficeException.class.getName().equals(className)) {
|
||||
messageCode = "reportException.failedConnectToOffice";
|
||||
} else if (e instanceof UnsupportedFormatException) {
|
||||
} else if (UnsupportedFormatException.class.getName().equals(className)) {
|
||||
messageCode = "reportException.unsupportedFileFormat";
|
||||
}
|
||||
String msg = MessageProvider.getMessage(getClass(), messageCode);
|
||||
|
@ -8,18 +8,22 @@ package com.haulmont.cuba.desktop.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.SilentException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handler that does nothing in respond to {@link SilentException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class SilentExceptionHandler extends AbstractExceptionHandler<SilentException> {
|
||||
public class SilentExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public SilentExceptionHandler() {
|
||||
super(SilentException.class);
|
||||
super(SilentException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Thread thread, SilentException e) {
|
||||
protected void doHandle(Thread thread, String className, String message, @Nullable Throwable throwable) {
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,14 @@ import com.haulmont.cuba.desktop.App;
|
||||
import com.haulmont.cuba.gui.ServiceLocator;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Handles database unique constraint violations. Determines the exception type by searching a special marker string
|
||||
* in the messages of all exceptions in the chain.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author devyatkin
|
||||
@ -48,7 +50,7 @@ public class UniqueConstraintViolationHandler implements ExceptionHandler {
|
||||
Throwable t = exception;
|
||||
try {
|
||||
while (t != null) {
|
||||
if (t.getMessage() != null && t.getMessage().contains(getMarker())) {
|
||||
if (t.toString().contains(getMarker())) {
|
||||
doHandle(thread, t);
|
||||
return true;
|
||||
}
|
||||
@ -62,7 +64,7 @@ public class UniqueConstraintViolationHandler implements ExceptionHandler {
|
||||
|
||||
protected void doHandle(Thread thread, Throwable e) {
|
||||
String constraintName = "";
|
||||
Matcher matcher = getPattern().matcher(e.getMessage());
|
||||
Matcher matcher = getPattern().matcher(e.toString());
|
||||
if (matcher.find()) {
|
||||
if (matcher.groupCount() > 1)
|
||||
constraintName = matcher.group(2);
|
||||
|
@ -53,6 +53,26 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Exception handlers -->
|
||||
|
||||
<bean id="cuba_exceptionHandlersConf" class="com.haulmont.cuba.desktop.exception.ExceptionHandlersConfiguration">
|
||||
<property name="handlerClasses">
|
||||
<list>
|
||||
<value>com.haulmont.cuba.desktop.exception.NoUserSessionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.SilentExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.UniqueConstraintViolationHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.AccessDeniedHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.NoSuchScreenHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.DeletePolicyHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.NumericOverflowExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.OptimisticExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.ReportExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.FileMissingExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.desktop.exception.EntityDeletedExceptionHandler</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Background Tasks -->
|
||||
|
||||
<bean id="cuba_BackgroundWorker_WatchDog" class="com.haulmont.cuba.gui.executors.TasksWatchDog"/>
|
||||
|
@ -1,24 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 25.12.2008 13:24:09
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.core.global;
|
||||
|
||||
import com.haulmont.cuba.core.sys.ClassesInfo;
|
||||
import com.haulmont.cuba.security.entity.PermissionType;
|
||||
|
||||
/**
|
||||
* This exception is raised on attempt to violate a security constraint
|
||||
* Exception that is raised on attempt to violate a security constraint.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class AccessDeniedException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = -3097861878301424338L;
|
||||
|
||||
static {
|
||||
ClassesInfo.addClientSupported(AccessDeniedException.class);
|
||||
}
|
||||
|
||||
private PermissionType type;
|
||||
|
||||
private String target;
|
||||
|
@ -11,9 +11,13 @@
|
||||
package com.haulmont.cuba.core.global;
|
||||
|
||||
/**
|
||||
* This exception is raised on attempt to soft delete an object,
|
||||
* which has linked objects marked with {@link OnDelete} annotation
|
||||
* with {@link com.haulmont.cuba.core.global.DeletePolicy} DENY value
|
||||
* Exception that is raised on attempt to soft delete an object,
|
||||
* which has linked objects marked with {@link com.haulmont.cuba.core.entity.annotation.OnDelete} annotation
|
||||
* with {@link com.haulmont.cuba.core.global.DeletePolicy#DENY} value.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class DeletePolicyException extends RuntimeException
|
||||
{
|
||||
|
@ -7,14 +7,12 @@
|
||||
package com.haulmont.cuba.core.global;
|
||||
|
||||
/**
|
||||
* This exception is raised on attempt to load a deleted object.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author pavlov
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is raised on attempt to load deleted object
|
||||
*/
|
||||
public class EntityDeletedException extends RuntimeException {
|
||||
public static final String ERR_MESSAGE = "Unable to load entiny because it has been deleted";
|
||||
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.global;
|
||||
|
||||
import com.haulmont.cuba.core.sys.ClassesInfo;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Exception that returns to clients from the middleware. Contains the information about the whole server-side
|
||||
* exception chain in the <code>Cause</code> objects list. Actual exception instances are included only if they
|
||||
* explicitly made available for the clients (registered in {@link ClassesInfo}).
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class RemoteException extends RuntimeException {
|
||||
|
||||
public static class Cause implements Serializable {
|
||||
|
||||
private String className;
|
||||
private String message;
|
||||
private Throwable throwable;
|
||||
|
||||
public Cause(Throwable throwable) {
|
||||
className = throwable.getClass().getName();
|
||||
message = throwable.getMessage();
|
||||
if (ClassesInfo.isClientSupported(throwable.getClass()))
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Throwable getThrowable() {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return className + ": " + message;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Cause> causes = new ArrayList<Cause>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public RemoteException(Throwable throwable) {
|
||||
List<Throwable> list = ExceptionUtils.getThrowableList(throwable);
|
||||
for (Throwable t : list) {
|
||||
causes.add(new Cause(t));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Cause> getCauses() {
|
||||
return Collections.unmodifiableList(causes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("RemoteException:");
|
||||
for (Cause cause : causes) {
|
||||
sb.append("\n---\n").append(cause.getClassName()).append(": ").append(cause.getMessage());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 15.01.2010 16:40:25
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.core.global;
|
||||
|
||||
/**
|
||||
* Exception that is used to interrupt an execution flow without any messages to the user.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class SilentException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 6598108074890603763L;
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that provides information about classes availability for different application layers.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class ClassesInfo {
|
||||
|
||||
private static List<Class> clientSupported = new ArrayList<Class>();
|
||||
|
||||
/**
|
||||
* Register a class as available for the client layer.
|
||||
* @param aClass class
|
||||
*/
|
||||
public static synchronized void addClientSupported(Class aClass) {
|
||||
if (!clientSupported.contains(aClass))
|
||||
clientSupported.add(aClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the class is available for the client layer.
|
||||
* @param aClass class
|
||||
* @return true if available
|
||||
*/
|
||||
public static synchronized boolean isClientSupported(Class aClass) {
|
||||
return clientSupported.contains(aClass);
|
||||
}
|
||||
}
|
@ -1,26 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 02.12.2008 13:14:32
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.security.global;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.core.sys.ClassesInfo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Raised by middleware if client provides an invalid user session ID (e.g. if the user session is expired)
|
||||
* Raised by middleware if the client provides an invalid user session ID (e.g. if the user session has expired).
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class NoUserSessionException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 4820628023682230319L;
|
||||
|
||||
static {
|
||||
ClassesInfo.addClientSupported(NoUserSessionException.class);
|
||||
}
|
||||
|
||||
public NoUserSessionException(UUID sessionId) {
|
||||
super(String.format("User session not found: %s", sessionId.toString()));
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 28.07.2009 10:05:20
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.gui;
|
||||
|
||||
/**
|
||||
* Raised on attempt to open an unknown screen.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class NoSuchScreenException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -3751833162235475862L;
|
||||
|
@ -155,8 +155,6 @@ entityLocked.desc=Record is locked by %s since %s
|
||||
|
||||
tooManyOpenTabs.message=Too many open tabs (Max %d).<br>Please close not used.
|
||||
|
||||
numericFieldOverflow.marker=Numeric field overflow
|
||||
|
||||
validationFail.caption=Alert
|
||||
validationFail=Input error
|
||||
invalidValue=Invalid value for "%s"
|
||||
|
@ -20,7 +20,7 @@ import com.haulmont.cuba.gui.AppConfig;
|
||||
import com.haulmont.cuba.gui.ServiceLocator;
|
||||
import com.haulmont.cuba.security.app.UserSessionService;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import com.haulmont.cuba.web.exception.*;
|
||||
import com.haulmont.cuba.web.exception.ExceptionHandlers;
|
||||
import com.haulmont.cuba.web.gui.WebTimer;
|
||||
import com.haulmont.cuba.web.log.AppLog;
|
||||
import com.haulmont.cuba.web.sys.ActiveDirectoryHelper;
|
||||
@ -243,25 +243,15 @@ public abstract class App extends Application
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be overridden in descendant to add application-specific exception handlers
|
||||
* Initializes exception handlers immediately after login and logout.
|
||||
* Can be overridden in descendants to manipulate exception handlers programmatically.
|
||||
* @param isConnected true after login, false after logout
|
||||
*/
|
||||
protected void initExceptionHandlers(boolean isConnected) {
|
||||
if (isConnected) {
|
||||
exceptionHandlers.addHandler(new NoUserSessionHandler()); // must be the first handler
|
||||
exceptionHandlers.addHandler(new SilentExceptionHandler());
|
||||
exceptionHandlers.addHandler(new UniqueConstraintViolationHandler());
|
||||
exceptionHandlers.addHandler(new AccessDeniedHandler());
|
||||
exceptionHandlers.addHandler(new NoSuchScreenHandler());
|
||||
exceptionHandlers.addHandler(new DeletePolicyHandler());
|
||||
exceptionHandlers.addHandler(new NumericOverflowExceptionHandler());
|
||||
exceptionHandlers.addHandler(new OptimisticExceptionHandler());
|
||||
exceptionHandlers.addHandler(new JPAOptimisticExceptionHandler());
|
||||
exceptionHandlers.addHandler(new ReportExceptionHandler());
|
||||
exceptionHandlers.addHandler(new FileMissingExceptionHandler());
|
||||
exceptionHandlers.addHandler(new InvalidValueExceptionHandler());
|
||||
exceptionHandlers.addHandler(new EntityDeletedExceptionHandler());
|
||||
exceptionHandlers.createByConfiguration();
|
||||
} else {
|
||||
exceptionHandlers.getHandlers().clear();
|
||||
exceptionHandlers.removeAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,35 +10,65 @@
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.vaadin.terminal.Terminal;
|
||||
import com.haulmont.cuba.core.global.RemoteException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.terminal.Terminal;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for exception handler bound to specific exception type.
|
||||
* <p>
|
||||
* If you need to handle a specific exception, create a descendant of this class,
|
||||
* pass handling exception class into constructor, implement {@link #doHandle(Throwable,com.haulmont.cuba.web.App)} method
|
||||
* and register the new handler in {@link App#initExceptionHandlers(boolean)}.
|
||||
* Base class for exception handlers determining their ability to handle an exception by its class name.
|
||||
*
|
||||
* <p>If you need to handle a specific exception, create a descendant of this class,
|
||||
* pass handling exception class names into constructor, implement
|
||||
* {@link #doHandle(com.haulmont.cuba.web.App, String, String, Throwable)} method
|
||||
* and register the new handler in the definition of {@link ExceptionHandlersConfiguration} bean in the client's
|
||||
* spring.xml.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public abstract class AbstractExceptionHandler<T extends Throwable> implements ExceptionHandler {
|
||||
public abstract class AbstractExceptionHandler implements ExceptionHandler {
|
||||
|
||||
private final Class<T> tClass;
|
||||
private List<String> classNames;
|
||||
|
||||
public AbstractExceptionHandler(Class<T> tClass) {
|
||||
this.tClass = tClass;
|
||||
protected AbstractExceptionHandler(String... classNames) {
|
||||
this.classNames = Arrays.asList(classNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Terminal.ErrorEvent event, App app) {
|
||||
Throwable t = event.getThrowable();
|
||||
while (t != null) {
|
||||
if (tClass.isAssignableFrom(t.getClass())) {
|
||||
doHandle((T) t, app);
|
||||
Throwable exception = event.getThrowable();
|
||||
List<Throwable> list = ExceptionUtils.getThrowableList(exception);
|
||||
for (Throwable throwable : list) {
|
||||
if (classNames.contains(throwable.getClass().getName())) {
|
||||
doHandle(app, throwable.getClass().getName(), throwable.getMessage(), throwable);
|
||||
return true;
|
||||
}
|
||||
t = t.getCause();
|
||||
if (throwable instanceof RemoteException) {
|
||||
RemoteException remoteException = (RemoteException) throwable;
|
||||
for (RemoteException.Cause cause : remoteException.getCauses()) {
|
||||
if (classNames.contains(cause.getClassName())) {
|
||||
doHandle(app, cause.getClassName(), cause.getMessage(), cause.getThrowable());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void doHandle(T t, App app);
|
||||
/**
|
||||
* Perform exception handling.
|
||||
* @param app current {@link App} instance
|
||||
* @param className actual exception class name
|
||||
* @param message exception message
|
||||
* @param throwable exception instance. Can be null if the exception occured on the server side and this
|
||||
* exception class isn't accessible by the client.
|
||||
*/
|
||||
protected abstract void doHandle(App app, String className, String message, @Nullable Throwable throwable);
|
||||
}
|
||||
|
@ -15,18 +15,28 @@ import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
public class AccessDeniedHandler extends AbstractExceptionHandler<AccessDeniedException> {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link AccessDeniedException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class AccessDeniedHandler extends AbstractExceptionHandler {
|
||||
|
||||
public AccessDeniedHandler() {
|
||||
super(AccessDeniedException.class);
|
||||
super(AccessDeniedException.class.getName());
|
||||
}
|
||||
|
||||
protected void doHandle(AccessDeniedException t, App app) {
|
||||
@Override
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "accessDenied.message");
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public void handle(AccessDeniedException e, App app) {
|
||||
doHandle(e, app);
|
||||
doHandle(app, AccessDeniedException.class.getName(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 20.05.2009 18:32:01
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
@ -18,19 +13,21 @@ import com.haulmont.cuba.web.App;
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* This exception handler comes into play if no other handler has handled the exception
|
||||
* This exception handler comes into play if no other handler in the chain has handled the exception.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class DefaultExceptionHandler implements ExceptionHandler
|
||||
{
|
||||
@Override
|
||||
public boolean handle(Terminal.ErrorEvent event, App app) {
|
||||
// Copied from com.vaadin.Application.terminalError()
|
||||
|
||||
Throwable t = event.getThrowable();
|
||||
if (t instanceof SocketException) {
|
||||
// Most likely client browser closed socket
|
||||
// System.err
|
||||
// .println("Warning: SocketException in CommunicationManager."
|
||||
// + " Most likely client (browser) closed socket.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -55,12 +52,6 @@ public class DefaultExceptionHandler implements ExceptionHandler
|
||||
((AbstractComponent) owner)
|
||||
.setComponentError(new SystemError(e));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Can't show it to the user in any way so we print to standard
|
||||
* error
|
||||
*/
|
||||
// t.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Ilya Grachev
|
||||
* Created: 29.07.2009 18:51:21
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
@ -19,6 +14,14 @@ import com.vaadin.ui.Window;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Handles {@link DeletePolicyException}. Determines the exception type by searching a special marker string in the
|
||||
* messages of all exceptions in the chain.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class DeletePolicyHandler implements ExceptionHandler {
|
||||
|
||||
@Override
|
||||
@ -26,8 +29,8 @@ public class DeletePolicyHandler implements ExceptionHandler {
|
||||
Throwable t = event.getThrowable();
|
||||
try {
|
||||
while (t != null) {
|
||||
if (t.getMessage() != null && t.getMessage().contains(getMarker())) {
|
||||
doHandle(t.getMessage(), app);
|
||||
if (t.toString().contains(getMarker())) {
|
||||
doHandle(t.toString(), app);
|
||||
return true;
|
||||
}
|
||||
t = t.getCause();
|
||||
|
@ -11,19 +11,23 @@ import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link EntityDeletedException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author pavlov
|
||||
*/
|
||||
public class EntityDeletedExceptionHandler extends AbstractExceptionHandler<EntityDeletedException> {
|
||||
public class EntityDeletedExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public EntityDeletedExceptionHandler() {
|
||||
super(EntityDeletedException.class);
|
||||
super(EntityDeletedException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(EntityDeletedException e, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.formatMessage(getClass(), "entityDeletedException.message");
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_WARNING_MESSAGE);
|
||||
}
|
||||
|
@ -18,7 +18,11 @@ import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.Button;
|
||||
|
||||
/**
|
||||
* This dialog can be used by exception handlers to show an information about error
|
||||
* This dialog can be used by exception handlers to show an information about error.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class ExceptionDialog extends Window
|
||||
{
|
||||
|
@ -16,9 +16,20 @@ import com.haulmont.cuba.web.App;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Interface implemented by unhandled exception handler in WebUI
|
||||
* Interface to be implemented by exception handlers in Web-client.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public interface ExceptionHandler extends Serializable
|
||||
{
|
||||
/**
|
||||
* Handle an exception. Implementation class should either handle the exception and return true, or return false
|
||||
* to delegate execution to the next handler in the chain of responsibility.
|
||||
* @param event error event containing the exception, generated by Vaadin
|
||||
* @param app current {@link App} instance
|
||||
* @return true if the exception has been succesfully handled, false if not
|
||||
*/
|
||||
boolean handle(Terminal.ErrorEvent event, App app);
|
||||
}
|
||||
|
@ -10,33 +10,51 @@
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.terminal.Terminal;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides extensible exception handling functionality.
|
||||
* See also {@link App#initExceptionHandlers(boolean)}
|
||||
* Class that holds the collection of exception handlers and delegates unhandled exception processing to them. Handlers
|
||||
* form the chain of responsibility.
|
||||
*
|
||||
* <p>A set of exception handlers is configured by defining <code>ExceptionHandlersConfiguration</code> beans
|
||||
* in spring.xml. If a project needs specific handlers, it should define a bean of such type with its own
|
||||
* <strong>id</strong>, e.g. <code>refapp_ExceptionHandlersConfiguration</code></p>
|
||||
*
|
||||
* <p>An instance of this class is bound to {@link App}.</p>
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class ExceptionHandlers implements Serializable
|
||||
{
|
||||
private LinkedList<ExceptionHandler> handlers = new LinkedList<ExceptionHandler>();
|
||||
|
||||
private App app;
|
||||
|
||||
private ExceptionHandler defaultHandler;
|
||||
|
||||
private static final long serialVersionUID = 1458946417299293127L;
|
||||
|
||||
protected App app;
|
||||
|
||||
protected LinkedList<ExceptionHandler> handlers = new LinkedList<ExceptionHandler>();
|
||||
|
||||
protected ExceptionHandler defaultHandler;
|
||||
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
|
||||
public ExceptionHandlers(App app) {
|
||||
this.app = app;
|
||||
this.defaultHandler = new DefaultExceptionHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new handler if it is not yet registered
|
||||
* Adds new handler if it is not yet registered.
|
||||
* @param handler handler instance
|
||||
*/
|
||||
public void addHandler(ExceptionHandler handler) {
|
||||
if (!handlers.contains(handler))
|
||||
@ -44,14 +62,16 @@ public class ExceptionHandlers implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* All registered handlers
|
||||
* Return all registered handlers.
|
||||
* @return modifiable handlers list
|
||||
*/
|
||||
public LinkedList<ExceptionHandler> getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates exception handling to registered handlers
|
||||
* Delegates exception handling to registered handlers.
|
||||
* @param event error event generated by Vaadin
|
||||
*/
|
||||
public void handle(Terminal.ErrorEvent event) {
|
||||
for (ExceptionHandler handler : handlers) {
|
||||
@ -60,4 +80,27 @@ public class ExceptionHandlers implements Serializable
|
||||
}
|
||||
defaultHandler.handle(event, app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all handlers defined by <code>ExceptionHandlersConfiguration</code> beans in spring.xml.
|
||||
*/
|
||||
public void createByConfiguration() {
|
||||
Map<String, ExceptionHandlersConfiguration> map = AppContext.getBeansOfType(ExceptionHandlersConfiguration.class);
|
||||
for (ExceptionHandlersConfiguration conf : map.values()) {
|
||||
for (Class aClass : conf.getHandlerClasses()) {
|
||||
try {
|
||||
addHandler(ReflectionHelper.<ExceptionHandler>newInstance(aClass));
|
||||
} catch (NoSuchMethodException e) {
|
||||
log.error("Unable to instantiate " + aClass, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all handlers.
|
||||
*/
|
||||
public void removeAll() {
|
||||
handlers.clear();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that is used to configure {@link ExceptionHandlers} via spring.xml.
|
||||
*
|
||||
* <p>If a project needs specific exception handlers, it should define a bean of this type with its own
|
||||
* <strong>id</strong>, e.g. <code>refapp_ExceptionHandlersConfiguration</code>, and set the list of handler class
|
||||
* names in <code>handlerClasses</code> property.</p>
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class ExceptionHandlersConfiguration {
|
||||
|
||||
private List<Class> handlerClasses = new ArrayList<Class>();
|
||||
|
||||
/**
|
||||
* Set the list of exception handler class names, usually from spring.xml.
|
||||
* @param list list of class names
|
||||
*/
|
||||
public void setHandlerClasses(List<String> list) {
|
||||
for (String className : list) {
|
||||
handlerClasses.add(ReflectionHelper.getClass(className));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of exception handler class names.
|
||||
* @return list of class names
|
||||
*/
|
||||
public List<Class> getHandlerClasses() {
|
||||
return handlerClasses;
|
||||
}
|
||||
}
|
@ -11,25 +11,30 @@ import com.haulmont.cuba.gui.export.FileMissingException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link FileMissingException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author artamonov
|
||||
*/
|
||||
public class FileMissingExceptionHandler extends AbstractExceptionHandler<FileMissingException> {
|
||||
public class FileMissingExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public FileMissingExceptionHandler() {
|
||||
super(FileMissingException.class);
|
||||
super(FileMissingException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(FileMissingException t, App app) {
|
||||
String msg = MessageProvider.formatMessage(getClass(), "fileNotFoundWarning.message", t.getFileName());
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
String fileName = throwable != null ? ((FileMissingException) throwable).getFileName() : "?";
|
||||
String msg = MessageProvider.formatMessage(getClass(), "fileNotFoundWarning.message", fileName);
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_WARNING_MESSAGE);
|
||||
}
|
||||
|
||||
public boolean handle(FileMissingException e, App app) {
|
||||
doHandle(e, app);
|
||||
doHandle(app, FileMissingException.class.getName(), e.getMessage(), e);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -11,19 +11,21 @@ import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.data.Validator;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author knst
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class InvalidValueExceptionHandler extends AbstractExceptionHandler<Validator.InvalidValueException> {
|
||||
public class InvalidValueExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public InvalidValueExceptionHandler() {
|
||||
super(Validator.InvalidValueException.class);
|
||||
super(Validator.InvalidValueException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(Validator.InvalidValueException e, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
app.getAppWindow().showNotification(
|
||||
MessageProvider.getMessage(getClass(), "validationFail.caption"),
|
||||
MessageProvider.getMessage(getClass(), "validationFail"),
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Maksim Tulupov
|
||||
* Created: 21.01.2010 10:07:21
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JPAOptimisticExceptionHandler extends AbstractExceptionHandler<OptimisticLockException> {
|
||||
|
||||
public JPAOptimisticExceptionHandler() {
|
||||
super(OptimisticLockException.class);
|
||||
}
|
||||
|
||||
protected void doHandle(OptimisticLockException e, App app) {
|
||||
Pattern pattern = Pattern.compile("\\[([^-]*)-");
|
||||
Matcher matcher = pattern.matcher(ExceptionUtils.getStackTrace(e));
|
||||
String entityClassName = "";
|
||||
if (matcher.find()) {
|
||||
entityClassName = matcher.group(1);
|
||||
}
|
||||
|
||||
String localizedEntityName = "";
|
||||
String entityName = entityClassName.substring(entityClassName.lastIndexOf(".") + 1);
|
||||
String packageName = entityClassName.substring(0, entityClassName.lastIndexOf("."));
|
||||
localizedEntityName = MessageProvider.getMessage(packageName, entityName);
|
||||
|
||||
String msg = MessageProvider.formatMessage(getClass(), "optimisticException.message", "\"" + localizedEntityName + "\"");
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
@ -10,23 +10,32 @@
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.gui.NoSuchScreenException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
public class NoSuchScreenHandler extends AbstractExceptionHandler<NoSuchScreenException> {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles {@link NoSuchScreenException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class NoSuchScreenHandler extends AbstractExceptionHandler {
|
||||
|
||||
public NoSuchScreenHandler() {
|
||||
super(NoSuchScreenException.class);
|
||||
super(NoSuchScreenException.class.getName());
|
||||
}
|
||||
|
||||
protected void doHandle(NoSuchScreenException t, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "noSuchScreen.message");
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public void handle(NoSuchScreenException e, App app) {
|
||||
doHandle(e, app);
|
||||
doHandle(app, NoSuchScreenException.class.getName(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 25.09.2009 15:07:23
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.gui.components.*;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.haulmont.cuba.security.global.NoUserSessionException;
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.gui.components.Action;
|
||||
import com.haulmont.cuba.gui.components.Component;
|
||||
import com.haulmont.cuba.gui.components.DialogAction;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
import com.haulmont.cuba.security.global.NoUserSessionException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.terminal.ExternalResource;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class NoUserSessionHandler extends AbstractExceptionHandler<NoUserSessionException> {
|
||||
/**
|
||||
* Handles {@link NoUserSessionException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class NoUserSessionHandler extends AbstractExceptionHandler {
|
||||
|
||||
private static Log log = LogFactory.getLog(NoUserSessionHandler.class);
|
||||
private Locale locale;
|
||||
|
||||
public NoUserSessionHandler() {
|
||||
super(NoUserSessionException.class);
|
||||
super(NoUserSessionException.class.getName());
|
||||
locale = App.getInstance().getConnection().getSession().getLocale();
|
||||
}
|
||||
|
||||
protected void doHandle(NoUserSessionException t, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
try {
|
||||
App.getInstance().getWindowManager().showOptionDialog(
|
||||
MessageProvider.getMessage(getClass(), "dialogs.Information", locale),
|
||||
|
@ -1,12 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Degtyarjov Eugeniy
|
||||
* Created: 17.11.2009 14:57:21
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.exception;
|
||||
@ -17,13 +12,23 @@ import com.vaadin.ui.Window;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.openjpa.lib.jdbc.ReportingSQLException;
|
||||
|
||||
public class NumericOverflowExceptionHandler extends AbstractExceptionHandler<ReportingSQLException> {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles database "numeric overflow" exception.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author degtyarjov
|
||||
*/
|
||||
public class NumericOverflowExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public NumericOverflowExceptionHandler() {
|
||||
super(ReportingSQLException.class);
|
||||
super(ReportingSQLException.class.getName());
|
||||
}
|
||||
|
||||
protected void doHandle(ReportingSQLException e, App app) {
|
||||
if (StringUtils.containsIgnoreCase(e.getMessage(), MessageProvider.getMessage(getClass(), "numericFieldOverflow.marker"))) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
if (StringUtils.containsIgnoreCase(message, "Numeric field overflow")) {
|
||||
String msg = MessageProvider.getMessage(getClass(), "numericFieldOverflow.message");
|
||||
app.getAppWindow().showNotification(msg, Window.Notification.TYPE_ERROR_MESSAGE);
|
||||
}
|
||||
|
@ -1,32 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: FIRSTNAME LASTNAME
|
||||
* Created: 25.12.2009 10:22:36
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageProvider;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
import org.apache.openjpa.util.OptimisticException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class OptimisticExceptionHandler extends AbstractExceptionHandler<OptimisticException>{
|
||||
/**
|
||||
* Handles a JPA optimistic lock exception.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class OptimisticExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public OptimisticExceptionHandler() {
|
||||
super(OptimisticException.class);
|
||||
super("org.springframework.orm.jpa.JpaOptimisticLockingFailureException");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(OptimisticException e, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
Pattern pattern = Pattern.compile("\\[([^-]*)-");
|
||||
Matcher matcher = pattern.matcher(e.getMessage());
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
String entityClassName = "";
|
||||
if (matcher.find()) {
|
||||
entityClassName = matcher.group(1);
|
||||
|
@ -1,12 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Yuryi Artamonov
|
||||
* Created: 06.10.2010 14:57:32
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
@ -17,17 +12,30 @@ import com.haulmont.cuba.report.exception.UnsupportedFormatException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
public class ReportExceptionHandler extends AbstractExceptionHandler<ReportingException> {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles reporting exceptions.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author artamonov
|
||||
*/
|
||||
public class ReportExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public ReportExceptionHandler() {
|
||||
super(ReportingException.class);
|
||||
super(
|
||||
ReportingException.class.getName(),
|
||||
FailedToConnectToOpenOfficeException.class.getName(),
|
||||
UnsupportedFormatException.class.getName()
|
||||
);
|
||||
}
|
||||
|
||||
protected void doHandle(ReportingException t, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
String messageCode = "reportException.message";
|
||||
if (t instanceof FailedToConnectToOpenOfficeException) {
|
||||
if (FailedToConnectToOpenOfficeException.class.getName().equals(className)) {
|
||||
messageCode = "reportException.failedConnectToOffice";
|
||||
} else if (t instanceof UnsupportedFormatException) {
|
||||
} else if (UnsupportedFormatException.class.getName().equals(className)) {
|
||||
messageCode = "reportException.unsupportedFileFormat";
|
||||
}
|
||||
String msg = MessageProvider.getMessage(getClass(), messageCode);
|
||||
@ -35,7 +43,7 @@ public class ReportExceptionHandler extends AbstractExceptionHandler<ReportingEx
|
||||
}
|
||||
|
||||
public boolean handle(ReportingException e, App app) {
|
||||
doHandle(e, app);
|
||||
doHandle(app, e.getClass().getName(), e.getMessage(), e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 15.01.2010 16:42:17
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.SilentException;
|
||||
import com.haulmont.cuba.web.App;
|
||||
|
||||
public class SilentExceptionHandler extends AbstractExceptionHandler<SilentException> {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handler that does nothing in respond to {@link SilentException}.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class SilentExceptionHandler extends AbstractExceptionHandler {
|
||||
|
||||
public SilentExceptionHandler() {
|
||||
super(SilentException.class);
|
||||
super(SilentException.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHandle(SilentException e, App app) {
|
||||
protected void doHandle(App app, String className, String message, @Nullable Throwable throwable) {
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2011 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Konstantin Krivopustov
|
||||
* Created: 21.05.2009 10:41:48
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.exception;
|
||||
|
||||
import com.haulmont.cuba.core.global.MessageUtils;
|
||||
import com.haulmont.cuba.gui.components.IFrame;
|
||||
import com.vaadin.terminal.Terminal;
|
||||
import com.haulmont.cuba.web.App;
|
||||
import com.haulmont.cuba.gui.ServiceLocator;
|
||||
@ -22,6 +16,14 @@ import org.apache.commons.lang.StringUtils;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Handles database unique constraint violations. Determines the exception type by searching a special marker string
|
||||
* in the messages of all exceptions in the chain.
|
||||
*
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
public class UniqueConstraintViolationHandler implements ExceptionHandler
|
||||
{
|
||||
private String marker;
|
||||
@ -43,11 +45,12 @@ public class UniqueConstraintViolationHandler implements ExceptionHandler
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Terminal.ErrorEvent event, App app) {
|
||||
Throwable t = event.getThrowable();
|
||||
try {
|
||||
while (t != null) {
|
||||
if (t.getMessage() != null && t.getMessage().contains(getMarker())) {
|
||||
if (t.toString().contains(getMarker())) {
|
||||
doHandle(t, app);
|
||||
return true;
|
||||
}
|
||||
@ -61,7 +64,7 @@ public class UniqueConstraintViolationHandler implements ExceptionHandler
|
||||
|
||||
private void doHandle(Throwable throwable, App app) {
|
||||
String constraintName = "";
|
||||
Matcher matcher = getPattern().matcher(throwable.getMessage());
|
||||
Matcher matcher = getPattern().matcher(throwable.toString());
|
||||
if (matcher.find()) {
|
||||
if (matcher.groupCount() > 1)
|
||||
constraintName = matcher.group(2);
|
||||
|
@ -76,7 +76,28 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Scheduling setup -->
|
||||
<!-- Exception handlers -->
|
||||
|
||||
<bean id="cuba_exceptionHandlersConf" class="com.haulmont.cuba.web.exception.ExceptionHandlersConfiguration">
|
||||
<property name="handlerClasses">
|
||||
<list>
|
||||
<value>com.haulmont.cuba.web.exception.NoUserSessionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.SilentExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.UniqueConstraintViolationHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.AccessDeniedHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.NoSuchScreenHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.DeletePolicyHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.NumericOverflowExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.OptimisticExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.ReportExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.FileMissingExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.InvalidValueExceptionHandler</value>
|
||||
<value>com.haulmont.cuba.web.exception.EntityDeletedExceptionHandler</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Spring scheduling setup -->
|
||||
|
||||
<bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
|
||||
<property name="daemon" value="true"/>
|
||||
@ -87,7 +108,7 @@
|
||||
<task:scheduled ref="cuba_FileUploading" method="clearTempDirectory" cron="0 0 0 * * 2,4,6"/>
|
||||
</task:scheduled-tasks>
|
||||
|
||||
<!-- Background Tasks -->
|
||||
<!-- Background tasks support -->
|
||||
|
||||
<bean id="cuba_BackgroundWorker_WatchDog" class="com.haulmont.cuba.gui.executors.TasksWatchDog"/>
|
||||
|
||||
@ -95,19 +116,4 @@
|
||||
<constructor-arg index="0" ref="cuba_BackgroundWorker_WatchDog"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
|
||||
For use BackgroundWorker in project add to {app}-web-spring.xml this sheduler definition:
|
||||
|
||||
<bean id="backgroundWorkerScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
|
||||
<property name="daemon" value="true"/>
|
||||
<property name="poolSize" value="1"/>
|
||||
</bean>
|
||||
|
||||
<task:scheduled-tasks scheduler="backgroundWorkerScheduler">
|
||||
<task:scheduled ref="cuba_BackgroundWorker_WatchDog" method="cleanupTasks" fixed-delay="2000"/>
|
||||
</task:scheduled-tasks>
|
||||
|
||||
-->
|
||||
|
||||
</beans>
|
Loading…
Reference in New Issue
Block a user