Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4f3ee39
Item 7767: basic setup of details section
labkey-ankurj Sep 14, 2020
66565b6
Per error type specific components / pages with details content
labkey-ankurj Sep 15, 2020
67debf9
help docs links and back button functionality
labkey-ankurj Sep 17, 2020
6956771
Permissions page handling of impersonated user
labkey-ankurj Sep 20, 2020
e8edecf
jest tests
labkey-ankurj Sep 21, 2020
4644051
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Sep 21, 2020
18949d1
upgrade ui-components alpha version
labkey-ankurj Sep 21, 2020
9f2adbc
stop impersonating button, address todos, remove old code
labkey-ankurj Sep 22, 2020
13f9091
remove todo
labkey-ankurj Sep 22, 2020
c95cb73
Code review feedback
labkey-nicka Sep 22, 2020
97c5eed
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Sep 22, 2020
9b19060
flip impersonating user and logged in user info
labkey-ankurj Sep 23, 2020
ac44ac9
handle the case when error page is displayed without an actual throwa…
labkey-ankurj Sep 24, 2020
cef1097
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Sep 25, 2020
ec06582
fix string in jsp errors
labkey-ankurj Sep 25, 2020
facc79c
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Sep 25, 2020
5590f3b
code review changes - css updates, text updates, html encoding
labkey-ankurj Sep 28, 2020
92d43ee
Merge branch 'develop' into fb_ErrorPage_7767
cnathe Sep 28, 2020
261b475
update css on stop impersonating button
labkey-ankurj Sep 28, 2020
8b04770
replace br tags with css prop
labkey-ankurj Sep 28, 2020
e04fdeb
Fix (mostly) for view details triangle pointer position issue with di…
cnathe Sep 28, 2020
cf6bef2
server side code review changes
labkey-ankurj Sep 29, 2020
dd4b8c9
more code review feedback changes
labkey-ankurj Sep 29, 2020
9cdc64b
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Sep 30, 2020
1ce8c9c
update ui-components version to release version
labkey-ankurj Oct 1, 2020
92da00b
jest test updates
labkey-ankurj Oct 1, 2020
868af9d
different subheading checks in jest tests for diff error types
labkey-ankurj Oct 1, 2020
8e5df94
fix ClientApiTest.webDavAPITest
labkey-ankurj Oct 1, 2020
37d6af1
fix ClientAPITest.contentTypeResponseTest
labkey-ankurj Oct 1, 2020
dbb4194
test text for impersonating user in permission error page
labkey-ankurj Oct 1, 2020
d404836
fix SecurityTest
labkey-ankurj Oct 2, 2020
006e67b
check if there are config exceptions during startup
labkey-ankurj Oct 2, 2020
d23bccf
revised wordings
labkey-ankurj Oct 5, 2020
19ae4c1
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Oct 5, 2020
44801fc
revised wordings update
labkey-ankurj Oct 5, 2020
36343bb
drop the extension to refer lib.xml in prod builds
labkey-ankurj Oct 6, 2020
ce38e75
add message to title
labkey-ankurj Oct 7, 2020
7bcda53
fix multiple Daily failures
labkey-ankurj Oct 7, 2020
febb96a
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Oct 7, 2020
9f6f09c
Request library definitions from root container
labkey-nicka Oct 7, 2020
1206d89
Merge branch 'develop' into fb_ErrorPage_7767
labkey-ankurj Oct 8, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 16 additions & 49 deletions api/src/org/labkey/api/util/ErrorRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.labkey.api.util;

import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.data.CoreSchema;
import org.labkey.api.data.DbSchema;
Expand All @@ -40,69 +41,30 @@ public class ErrorRenderer
private final boolean _isStartupFailure;
private final ErrorRendererProperties _errorRendererProps;
private final String _title;

// TODO: ErrorPage use these in React app
private boolean _includeHomeButton = true;
private boolean _includeBackButton = true;
private boolean _includeFolderButton = true;
private boolean _includeStopImpersonatingButton = false;
private final String _errorCode;

private ErrorType _errorType;

enum ErrorType
public String getStackTrace()
{
return ExceptionUtils.getStackTrace(getException());
}

public enum ErrorType
{
notFound,
permission,
configuration,
execution
}

public boolean isIncludeHomeButton()
{
return _includeHomeButton;
}

public void setIncludeHomeButton(boolean includeHomeButton)
{
_includeHomeButton = includeHomeButton;
}

public boolean isIncludeBackButton()
{
return _includeBackButton;
}

public void setIncludeBackButton(boolean includeBackButton)
{
_includeBackButton = includeBackButton;
}

public boolean isIncludeFolderButton()
{
return _includeFolderButton;
}

public void setIncludeFolderButton(boolean includeFolderButton)
{
_includeFolderButton = includeFolderButton;
}

public boolean isIncludeStopImpersonatingButton()
{
return _includeStopImpersonatingButton;
}

public void setIncludeStopImpersonatingButton(boolean includeStopImpersonatingButton)
{
_includeStopImpersonatingButton = includeStopImpersonatingButton;
}

ErrorRenderer(int status, String heading, Throwable x, boolean isStartupFailure)
ErrorRenderer(int status, String errorCode, String heading, Throwable x, boolean isStartupFailure)
{
_status = status;
_exception = x;
_isStartupFailure = isStartupFailure;
_errorRendererProps = (x instanceof ErrorRendererProperties ? (ErrorRendererProperties)x : null);
_errorCode = errorCode;

if (null == _errorRendererProps)
{
Expand All @@ -111,7 +73,7 @@ public void setIncludeStopImpersonatingButton(boolean includeStopImpersonatingBu
}
else
{
_heading = _errorRendererProps.getHeading(_isStartupFailure);
_heading = null != heading ? heading : _errorRendererProps.getHeading(_isStartupFailure);
_title = _errorRendererProps.getTitle();
}
}
Expand Down Expand Up @@ -301,4 +263,9 @@ public void setErrorType(ErrorType errorType)
{
_errorType = errorType;
}

public String getErrorCode()
{
return _errorCode;
}
}
12 changes: 0 additions & 12 deletions api/src/org/labkey/api/util/ErrorTemplate.java

This file was deleted.

239 changes: 13 additions & 226 deletions api/src/org/labkey/api/util/ErrorView.java
Original file line number Diff line number Diff line change
@@ -1,226 +1,13 @@
/*
* Copyright (c) 2009-2019 LabKey Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.labkey.api.util;

import org.apache.commons.lang3.StringUtils;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerManager;
import org.labkey.api.portal.ProjectUrls;
import org.labkey.api.security.LoginUrls;
import org.labkey.api.settings.AppProps;
import org.labkey.api.settings.LookAndFeelProperties;
import org.labkey.api.view.ActionURL;
import org.labkey.api.view.HttpView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

class ErrorView extends HttpView
{
private final ErrorRenderer _renderer;
private final boolean _startupFailure;
private final boolean _popup;

private ButtonBarRenderer _bbr = null;

private boolean _includeHomeButton = true;
private boolean _includeBackButton = true;
private boolean _includeFolderButton = true;
private boolean _includeStopImpersonatingButton = false;

ErrorView(ErrorRenderer renderer, boolean startupFailure)
{
this(renderer, startupFailure, false);
}

ErrorView(ErrorRenderer renderer, boolean startupFailure, boolean popup)
{
_renderer = renderer;
_startupFailure = startupFailure;
_popup = popup;
}


@Override
public void renderInternal(Object model, HttpServletRequest request, HttpServletResponse response) throws Exception
{
PrintWriter out = response.getWriter();

doStartTag(out);
_renderer.renderContent(out, request, _bbr);
doEndTag(out);
}


public void doStartTag(PrintWriter out)
{
Container c = null;

out.println("<!DOCTYPE html>");
out.println("<html><head>");

// If it's a startup failure we likely don't have a database, so don't try to handle containers. Instead, hard-code
// some reasonable styles.
if (!_startupFailure)
{
out.println(PageFlowUtil.getStandardIncludes(getViewContext(), null, false));

c = getViewContext().getContainer();
}
else
{
out.println("<style type=\"text/css\">\n" +
"<!--\n" +
"body {font-family:verdana,arial,helvetica,sans-serif;)}\n" +
"-->\n" +
"</style>");
}

if (null == c)
{
try
{
c = ContainerManager.getRoot();
}
catch (Throwable t)
{
// Exception at initial bootstrap (e.g., database not supported) might result in no root
}
}

//NOTE: Selenium tests expect errors to start with error number and include word "Error" in title
out.println("<title>" + PageFlowUtil.filter(_renderer.getTitle()) + "</title>");
out.println("</head><body style=\"margin:40px;\">");
_renderer.renderStart(out);

if (null != _renderer.getHeading())
{
out.println("<h3 class=\"labkey-error\">" + PageFlowUtil.filter(_renderer.getHeading()) + "</h3>");
}

// Why don't we just use c below?
Container contextContainer = getContextContainer();

if (null == contextContainer)
contextContainer = c;

// These buttons are useless if the server fails to start up. Also, they try to hit a database that probably doesn't exist.
if (!_startupFailure)
{
if (_renderer.getStatus() == HttpServletResponse.SC_UNAUTHORIZED)
{
if (getViewContext().getUser().isGuest())
{
ActionURL url = PageFlowUtil.urlProvider(LoginUrls.class).getLoginURL(getViewContext().getContainer(), null);
out.println("<p>You are not currently logged in. You may need to <a href=\"" + url + "\">log in</a> to gain the necessary permissions.</a></p>");
}
LookAndFeelProperties props = LookAndFeelProperties.getInstance(contextContainer);
if (!StringUtils.isBlank(props.getSupportEmail()))
{
out.println("<p>If you believe you should have permission to perform this action, please <a href=\"mailto:");
out.println(PageFlowUtil.filter(props.getSupportEmail()));
out.println("?subject=Permissions on ");
if (!StringUtils.isBlank(props.getShortName()))
{
out.println(PageFlowUtil.filter(props.getShortName()));
}
out.println("\">email your system administrator</a>.</p>");
}
}

if (_popup)
{
out.print(PageFlowUtil.button("Close").href("#").onClick("window.close(); return false;"));
out.println("<br>");
}
else
{
_bbr = new ErrorButtonBarRenderer(c);
}
}
}

private class ErrorButtonBarRenderer implements ButtonBarRenderer
{
private Container _c;

ErrorButtonBarRenderer(Container c)
{
_c = c;
}

@Override
public void render(PrintWriter out)
{
doButtonBar(out, _c);
}
}

private void doButtonBar(PrintWriter out, Container c)
{
if (_includeHomeButton)
{
out.print(PageFlowUtil.button("Home").href(AppProps.getInstance().getHomePageActionURL()));
out.print("&nbsp;");
}
if (_includeBackButton)
{
out.print(PageFlowUtil.generateBackButton());
out.print("&nbsp;");
}
if (_includeFolderButton && !c.isRoot())
{
ActionURL folderURL = PageFlowUtil.urlProvider(ProjectUrls.class).getStartURL(c);
out.print(PageFlowUtil.button("Folder").href(folderURL));
out.print("&nbsp;");
}
if (_includeStopImpersonatingButton)
{
ActionURL stopUrl = PageFlowUtil.urlProvider(LoginUrls.class).getStopImpersonatingURL(c, getViewContext().getActionURL());
out.println(PageFlowUtil.button("Stop Impersonating").href(stopUrl).usePost());
}

out.println("<br>");
}

public void doEndTag(PrintWriter out)
{
_renderer.renderEnd(out);
out.println("</body></html>");
}

public void setIncludeHomeButton(boolean includeHomeButton)
{
_includeHomeButton = includeHomeButton;
}

public void setIncludeBackButton(boolean includeBackButton)
{
_includeBackButton = includeBackButton;
}

public void setIncludeFolderButton(boolean includeFolderButton)
{
_includeFolderButton = includeFolderButton;
}

public void setIncludeStopImpersonatingButton(boolean includeStopImpersonatingButton)
{
_includeStopImpersonatingButton = includeStopImpersonatingButton;
}
}
package org.labkey.api.util;

import org.labkey.api.view.JspView;

public class ErrorView extends JspView<ErrorRenderer>
{
public static String ERROR_PAGE_TITLE = "Error Page";

public ErrorView(ErrorRenderer renderer)
{
super("/org/labkey/api/view/template/errorView.jsp", renderer);
}
}
Loading