mirror of
https://gitee.com/jmix/cuba.git
synced 2024-11-30 18:27:56 +08:00
UI uncaught exceptions handling
This commit is contained in:
parent
77971c6932
commit
febd2fc680
@ -13,6 +13,7 @@ package com.haulmont.cuba.web;
|
|||||||
import com.haulmont.cuba.security.global.UserSession;
|
import com.haulmont.cuba.security.global.UserSession;
|
||||||
import com.haulmont.cuba.web.config.MenuConfig;
|
import com.haulmont.cuba.web.config.MenuConfig;
|
||||||
import com.haulmont.cuba.web.ScreenManager;
|
import com.haulmont.cuba.web.ScreenManager;
|
||||||
|
import com.haulmont.cuba.web.log.AppLog;
|
||||||
import com.haulmont.cuba.web.config.ActionConfig;
|
import com.haulmont.cuba.web.config.ActionConfig;
|
||||||
import com.itmill.toolkit.Application;
|
import com.itmill.toolkit.Application;
|
||||||
import com.itmill.toolkit.terminal.Terminal;
|
import com.itmill.toolkit.terminal.Terminal;
|
||||||
@ -37,6 +38,8 @@ public class App extends Application implements ConnectionListener
|
|||||||
|
|
||||||
private ScreenManager screenManager;
|
private ScreenManager screenManager;
|
||||||
|
|
||||||
|
private AppLog appLog;
|
||||||
|
|
||||||
private static ThreadLocal<App> currentApp = new ThreadLocal<App>();
|
private static ThreadLocal<App> currentApp = new ThreadLocal<App>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -44,6 +47,7 @@ public class App extends Application implements ConnectionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
public App() {
|
public App() {
|
||||||
|
appLog = new AppLog();
|
||||||
connection = new Connection();
|
connection = new Connection();
|
||||||
connection.addListener(this);
|
connection.addListener(this);
|
||||||
screenManager = new ScreenManager(this);
|
screenManager = new ScreenManager(this);
|
||||||
@ -91,12 +95,21 @@ public class App extends Application implements ConnectionListener
|
|||||||
return screenManager;
|
return screenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AppLog getAppLog() {
|
||||||
|
return appLog;
|
||||||
|
}
|
||||||
|
|
||||||
public void connectionStateChanged(Connection connection) {
|
public void connectionStateChanged(Connection connection) {
|
||||||
if (!connection.isConnected()) {
|
if (!connection.isConnected()) {
|
||||||
menuConfig = null;
|
menuConfig = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void terminalError(Terminal.ErrorEvent event) {
|
||||||
|
super.terminalError(event);
|
||||||
|
getAppLog().log(event);
|
||||||
|
}
|
||||||
|
|
||||||
private class RequestListener implements ApplicationContext.TransactionListener
|
private class RequestListener implements ApplicationContext.TransactionListener
|
||||||
{
|
{
|
||||||
public void transactionStart(Application application, Object transactionData) {
|
public void transactionStart(Application application, Object transactionData) {
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.haulmont.cuba.web;
|
package com.haulmont.cuba.web;
|
||||||
|
|
||||||
import com.itmill.toolkit.ui.*;
|
import com.haulmont.cuba.web.log.LogWindow;
|
||||||
import com.haulmont.cuba.web.Navigator;
|
|
||||||
import com.haulmont.cuba.web.resource.Messages;
|
import com.haulmont.cuba.web.resource.Messages;
|
||||||
|
import com.itmill.toolkit.ui.*;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -77,12 +77,24 @@ public class AppWindow extends Window implements ConnectionListener
|
|||||||
);
|
);
|
||||||
logoutBtn.setStyleName(Button.STYLE_LINK);
|
logoutBtn.setStyleName(Button.STYLE_LINK);
|
||||||
|
|
||||||
|
Button viewLogBtn = new Button(Messages.getString("viewLogBtn"),
|
||||||
|
new Button.ClickListener()
|
||||||
|
{
|
||||||
|
public void buttonClick(Button.ClickEvent event) {
|
||||||
|
LogWindow logWindow = new LogWindow();
|
||||||
|
addWindow(logWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
viewLogBtn.setStyleName(Button.STYLE_LINK);
|
||||||
|
|
||||||
ExpandLayout titleLayout = new ExpandLayout(ExpandLayout.ORIENTATION_HORIZONTAL);
|
ExpandLayout titleLayout = new ExpandLayout(ExpandLayout.ORIENTATION_HORIZONTAL);
|
||||||
titleLayout.setSpacing(true);
|
titleLayout.setSpacing(true);
|
||||||
titleLayout.setHeight(-1);
|
titleLayout.setHeight(-1);
|
||||||
titleLayout.addComponent(navBtn);
|
titleLayout.addComponent(navBtn);
|
||||||
titleLayout.addComponent(label);
|
titleLayout.addComponent(label);
|
||||||
titleLayout.addComponent(logoutBtn);
|
titleLayout.addComponent(logoutBtn);
|
||||||
|
titleLayout.addComponent(viewLogBtn);
|
||||||
titleLayout.expand(navBtn);
|
titleLayout.expand(navBtn);
|
||||||
|
|
||||||
rootLayout.addComponent(titleLayout);
|
rootLayout.addComponent(titleLayout);
|
||||||
|
@ -12,6 +12,7 @@ package com.haulmont.cuba.web;
|
|||||||
|
|
||||||
import com.haulmont.cuba.web.App;
|
import com.haulmont.cuba.web.App;
|
||||||
import com.haulmont.cuba.web.ScreenOpenType;
|
import com.haulmont.cuba.web.ScreenOpenType;
|
||||||
|
import com.haulmont.cuba.web.log.LogLevel;
|
||||||
import com.haulmont.cuba.web.config.ScreenAction;
|
import com.haulmont.cuba.web.config.ScreenAction;
|
||||||
import com.haulmont.cuba.web.ui.Screen;
|
import com.haulmont.cuba.web.ui.Screen;
|
||||||
import com.haulmont.cuba.web.ui.ScreenTitlePane;
|
import com.haulmont.cuba.web.ui.ScreenTitlePane;
|
||||||
@ -50,6 +51,7 @@ public class ScreenManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Screen openScreen(ScreenOpenType type, String actionName, String tabCaption) {
|
public Screen openScreen(ScreenOpenType type, String actionName, String tabCaption) {
|
||||||
|
app.getAppLog().debug("Opening screen " + actionName);
|
||||||
ScreenAction action = app.getActionConfig().getAction(actionName);
|
ScreenAction action = app.getActionConfig().getAction(actionName);
|
||||||
if (tabCaption == null)
|
if (tabCaption == null)
|
||||||
tabCaption = action.getCaption();
|
tabCaption = action.getCaption();
|
||||||
@ -106,7 +108,7 @@ public class ScreenManager
|
|||||||
|
|
||||||
TabInfo tabInfo = tabs.get(layout);
|
TabInfo tabInfo = tabs.get(layout);
|
||||||
if (tabInfo == null)
|
if (tabInfo == null)
|
||||||
throw new IllegalStateException("Current tab not found");
|
throw new IllegalStateException("Unable to close screen: current tab not found");
|
||||||
|
|
||||||
Screen screen = tabInfo.screens.getLast();
|
Screen screen = tabInfo.screens.getLast();
|
||||||
if (!screen.onClose()) {
|
if (!screen.onClose()) {
|
||||||
|
90
modules/web/src/com/haulmont/cuba/web/log/AppLog.java
Normal file
90
modules/web/src/com/haulmont/cuba/web/log/AppLog.java
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||||
|
* Haulmont Technology proprietary and confidential.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
|
||||||
|
* Author: Konstantin Krivopustov
|
||||||
|
* Created: 16.12.2008 11:09:01
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
package com.haulmont.cuba.web.log;
|
||||||
|
|
||||||
|
import com.itmill.toolkit.terminal.ParameterHandler;
|
||||||
|
import com.itmill.toolkit.terminal.Terminal;
|
||||||
|
import com.itmill.toolkit.terminal.URIHandler;
|
||||||
|
import com.itmill.toolkit.terminal.VariableOwner;
|
||||||
|
import com.itmill.toolkit.terminal.gwt.server.ChangeVariablesErrorEvent;
|
||||||
|
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AppLog
|
||||||
|
{
|
||||||
|
private LinkedList<LogItem> items = new LinkedList<LogItem>();
|
||||||
|
|
||||||
|
private int capacity = 100;
|
||||||
|
|
||||||
|
public void log(LogItem item) {
|
||||||
|
if (items.size() >= capacity) {
|
||||||
|
items.removeLast();
|
||||||
|
}
|
||||||
|
items.addFirst(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(LogLevel level, String message, Throwable throwable) {
|
||||||
|
log(new LogItem(level, message, throwable));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(String message) {
|
||||||
|
log(new LogItem(LogLevel.DEBUG, message, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void info(String message) {
|
||||||
|
log(new LogItem(LogLevel.INFO, message, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void warning(String message) {
|
||||||
|
log(new LogItem(LogLevel.WARNING, message, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(String message) {
|
||||||
|
log(new LogItem(LogLevel.ERROR, message, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(Terminal.ErrorEvent event) {
|
||||||
|
Throwable t = event.getThrowable();
|
||||||
|
if (t instanceof SocketException) {
|
||||||
|
// Most likely client browser closed socket
|
||||||
|
LogItem item = new LogItem(LogLevel.WARNING, "SocketException in CommunicationManager. Most likely client (browser) closed socket.", null);
|
||||||
|
log(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds the original source of the error/exception
|
||||||
|
Object owner = null;
|
||||||
|
if (event instanceof VariableOwner.ErrorEvent) {
|
||||||
|
owner = ((VariableOwner.ErrorEvent) event).getVariableOwner();
|
||||||
|
} else if (event instanceof URIHandler.ErrorEvent) {
|
||||||
|
owner = ((URIHandler.ErrorEvent) event).getURIHandler();
|
||||||
|
} else if (event instanceof ParameterHandler.ErrorEvent) {
|
||||||
|
owner = ((ParameterHandler.ErrorEvent) event).getParameterHandler();
|
||||||
|
} else if (event instanceof ChangeVariablesErrorEvent) {
|
||||||
|
owner = ((ChangeVariablesErrorEvent) event).getComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
if (owner != null)
|
||||||
|
msg.append("[").append(owner.getClass().getName()).append("] ");
|
||||||
|
msg.append("Uncaught throwable:");
|
||||||
|
|
||||||
|
LogItem item = new LogItem(LogLevel.ERROR, msg.toString(), t);
|
||||||
|
log(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LogItem> getItems() {
|
||||||
|
return new ArrayList<LogItem>(items);
|
||||||
|
}
|
||||||
|
}
|
46
modules/web/src/com/haulmont/cuba/web/log/LogItem.java
Normal file
46
modules/web/src/com/haulmont/cuba/web/log/LogItem.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||||
|
* Haulmont Technology proprietary and confidential.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
|
||||||
|
* Author: Konstantin Krivopustov
|
||||||
|
* Created: 16.12.2008 11:09:18
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
package com.haulmont.cuba.web.log;
|
||||||
|
|
||||||
|
import com.haulmont.cuba.core.global.TimeProvider;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class LogItem
|
||||||
|
{
|
||||||
|
private Date timestamp;
|
||||||
|
private LogLevel level;
|
||||||
|
private String message;
|
||||||
|
private Throwable throwable;
|
||||||
|
|
||||||
|
public LogItem(LogLevel level, String message, Throwable throwable) {
|
||||||
|
this.timestamp = TimeProvider.currentTimestamp();
|
||||||
|
this.level = level;
|
||||||
|
this.message = message;
|
||||||
|
this.throwable = throwable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogLevel getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getThrowable() {
|
||||||
|
return throwable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
}
|
19
modules/web/src/com/haulmont/cuba/web/log/LogLevel.java
Normal file
19
modules/web/src/com/haulmont/cuba/web/log/LogLevel.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||||
|
* Haulmont Technology proprietary and confidential.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
|
||||||
|
* Author: Konstantin Krivopustov
|
||||||
|
* Created: 16.12.2008 11:26:19
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
package com.haulmont.cuba.web.log;
|
||||||
|
|
||||||
|
public enum LogLevel
|
||||||
|
{
|
||||||
|
DEBUG,
|
||||||
|
INFO,
|
||||||
|
WARNING,
|
||||||
|
ERROR
|
||||||
|
}
|
77
modules/web/src/com/haulmont/cuba/web/log/LogWindow.java
Normal file
77
modules/web/src/com/haulmont/cuba/web/log/LogWindow.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||||
|
* Haulmont Technology proprietary and confidential.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
|
||||||
|
* Author: Konstantin Krivopustov
|
||||||
|
* Created: 16.12.2008 12:01:45
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
package com.haulmont.cuba.web.log;
|
||||||
|
|
||||||
|
import com.itmill.toolkit.ui.Window;
|
||||||
|
import com.itmill.toolkit.ui.Label;
|
||||||
|
import com.itmill.toolkit.ui.Button;
|
||||||
|
import com.itmill.toolkit.ui.ExpandLayout;
|
||||||
|
import com.haulmont.cuba.web.resource.Messages;
|
||||||
|
import com.haulmont.cuba.web.App;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.time.DateFormatUtils;
|
||||||
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
|
|
||||||
|
public class LogWindow extends Window
|
||||||
|
{
|
||||||
|
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
public LogWindow() {
|
||||||
|
super(Messages.getString("logWindow.caption"));
|
||||||
|
setHeight("80%");
|
||||||
|
setWidth("80%");
|
||||||
|
initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initUI() {
|
||||||
|
ExpandLayout layout = new ExpandLayout(ExpandLayout.ORIENTATION_VERTICAL);
|
||||||
|
layout.setSpacing(true);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
final Label label = new Label();
|
||||||
|
label.setContentMode(Label.CONTENT_UIDL);
|
||||||
|
label.setValue(writeLog());
|
||||||
|
|
||||||
|
Button refreshBtn = new Button(Messages.getString("logWindow.refreshBtn"),
|
||||||
|
new Button.ClickListener()
|
||||||
|
{
|
||||||
|
public void buttonClick(Button.ClickEvent event) {
|
||||||
|
label.setValue(writeLog());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
addComponent(refreshBtn);
|
||||||
|
addComponent(label);
|
||||||
|
layout.expand(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String writeLog() {
|
||||||
|
List<LogItem> items = App.getInstance().getAppLog().getItems();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (LogItem item : items) {
|
||||||
|
sb.append("<b>");
|
||||||
|
sb.append(DateFormatUtils.format(item.getTimestamp(), DATE_FORMAT));
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(item.getLevel().name());
|
||||||
|
sb.append("</b> ");
|
||||||
|
sb.append(item.getMessage());
|
||||||
|
if (item.getThrowable() != null) {
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(ExceptionUtils.getStackTrace(item.getThrowable()).replace("\n", "<br>"));
|
||||||
|
}
|
||||||
|
sb.append("<br>");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -9,9 +9,16 @@ action-config.sec$Role.browse=Browse Roles
|
|||||||
action-config.sec$User.browse=Browse Users
|
action-config.sec$User.browse=Browse Users
|
||||||
|
|
||||||
application.caption=Cuba Application
|
application.caption=Cuba Application
|
||||||
|
|
||||||
welcomeLabel=Hello from Cuba!
|
welcomeLabel=Hello from Cuba!
|
||||||
navBtn=Navigator
|
navBtn=Navigator
|
||||||
logoutBtn=Logout
|
logoutBtn=Logout
|
||||||
loggedInLabel=Logged in as %s
|
loggedInLabel=Logged in as %s
|
||||||
|
viewLogBtn=View Log
|
||||||
|
|
||||||
|
closeBtn=Close
|
||||||
|
|
||||||
navigator.caption=Navigator
|
navigator.caption=Navigator
|
||||||
closeBtn=Close
|
|
||||||
|
logWindow.caption=Application Log
|
||||||
|
logWindow.refreshBtn=Refresh
|
Loading…
Reference in New Issue
Block a user