You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/01/29 01:11:03 UTC
svn commit: r616118 - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry/internal/services/
tapestry-core/src/main/java/org/apache/tapestry/internal/structure/
tapestry-core/src/main/java/org/apache/tapestry/runtime/ tapestry...
Author: hlship
Date: Mon Jan 28 16:11:01 2008
New Revision: 616118
URL: http://svn.apache.org/viewvc?rev=616118&view=rev
Log:
TAPESTRY-2097: Render exceptions should identify the components that are actively rendering
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/RenderErrorDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java?rev=616118&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java Mon Jan 28 16:11:01 2008
@@ -0,0 +1,34 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// 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.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+public class RenderQueueException extends TapestryException
+{
+ private final Object[] _activeComponentIds;
+
+ public RenderQueueException(String message, Object[] activeComponentIds, Throwable cause)
+ {
+ super(message, cause);
+
+ _activeComponentIds = activeComponentIds;
+ }
+
+ public Object[] getActiveComponentIds()
+ {
+ return _activeComponentIds;
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java Mon Jan 28 16:11:01 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package org.apache.tapestry.internal.services;
import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.internal.util.Defense;
import org.apache.tapestry.ioc.util.Stack;
import org.apache.tapestry.runtime.RenderCommand;
import org.apache.tapestry.runtime.RenderQueue;
@@ -26,6 +27,8 @@
private final Stack<RenderCommand> _queue = new Stack<RenderCommand>(INITIAL_QUEUE_DEPTH);
+ private final Stack<String> _nestedIds = new Stack<String>(INITIAL_QUEUE_DEPTH);
+
private final Logger _logger;
public RenderQueueImpl(Logger logger)
@@ -63,9 +66,23 @@
// This will likely leave the page in a dirty state, and it will not go back into the
// page pool.
- _logger.error(ServicesMessages.renderQueueError(command, ex), ex);
+ String message = ServicesMessages.renderQueueError(command, ex);
+
+ _logger.error(message, ex);
- throw ex;
+ throw new RenderQueueException(message, _nestedIds.getSnapshot(), ex);
}
+ }
+
+ public void startComponent(String componentId)
+ {
+ Defense.notBlank(componentId, "componentId");
+
+ _nestedIds.push(componentId);
+ }
+
+ public void endComponent()
+ {
+ _nestedIds.pop();
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Mon Jan 28 16:11:01 2008
@@ -52,6 +52,17 @@
*/
public class ComponentPageElementImpl extends BaseLocatable implements ComponentPageElement, PageLifecycleListener
{
+ /**
+ * @see #render(org.apache.tapestry.MarkupWriter, org.apache.tapestry.runtime.RenderQueue)
+ */
+ private static final RenderCommand POP_COMPONENT_ID = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ queue.endComponent();
+ }
+ };
+
private static final ComponentCallback CONTAINING_PAGE_DID_ATTACH = new ComponentCallback()
{
public void run(Component component)
@@ -892,6 +903,7 @@
return String.format("%s[%s]", phaseName, _completeId);
}
+
/**
* Pushes the SetupRender phase state onto the queue.
*/
@@ -903,6 +915,10 @@
// Once we start rendering, the page is considered dirty, until we cleanup post render.
_page.incrementDirtyCount();
+
+ queue.startComponent(_completeId);
+
+ queue.push(POP_COMPONENT_ID);
queue.push(_setupRender);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java Mon Jan 28 16:11:01 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
package org.apache.tapestry.runtime;
/**
- * A stateful object that manages the process of rendering a page. Rending a page in Tapestry is
- * based on a command queue.
+ * A stateful object that manages the process of rendering a page. Rending a page in Tapestry is based on a command
+ * queue.
*/
public interface RenderQueue
{
@@ -24,4 +24,18 @@
* Adds the new command to the front of the queue.
*/
void push(RenderCommand command);
+
+ /**
+ * Indicates that a component is starting its render. A stack of active component ids is used for exception
+ * reporting.
+ *
+ * @param componentId of component that is rendering
+ */
+ void startComponent(String componentId);
+
+ /**
+ * Corresponds to {@link #startComponent(String)}, used to denote when the most recently started component finishes
+ * rendering.
+ */
+ void endComponent();
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/RenderErrorDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/RenderErrorDemo.tml?rev=616118&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/RenderErrorDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/RenderErrorDemo.tml Mon Jan 28 16:11:01 2008
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Render Error Demo</h1>
+
+ <p>This page will not completely render, it gets an exception.</p>
+
+ <t:Echo value="value"/>
+
+</html>
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Mon Jan 28 16:11:01 2008
@@ -1522,4 +1522,21 @@
assertSourcePresent("<ul><li>1</li><li>3</li><li>5</li><li>7</li><li>9</li></ul>");
}
+
+ /**
+ * TAPESTRY-2097
+ */
+ @Test
+ public void render_queue_exception()
+ {
+ start("Render Error Demo");
+
+ assertTextPresent("An unexpected application exception has occurred");
+
+ for (String s : new String[]{"RenderErrorDemo", "RenderErrorDemo:border", "RenderErrorDemo:echo"})
+ {
+ assertSourcePresent(String.format("<li>%s</li>", s));
+ }
+
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java?rev=616118&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java Mon Jan 28 16:11:01 2008
@@ -0,0 +1,24 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// 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.apache.tapestry.integration.app1.pages;
+
+public class RenderErrorDemo
+{
+ public Object getValue()
+ {
+ throw new RuntimeException("Exception thrown from getValue().");
+ }
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java Mon Jan 28 16:11:01 2008
@@ -61,6 +61,8 @@
private static final List<Item> ITEMS = CollectionFactory.newList(
new Item("actionpage", "Action Page", "tests fixture for ActionLink component"),
+ new Item("RenderErrorDemo", "Render Error Demo", "reporting of errors while rendering"),
+
new Item("nested/AssetDemo", "AssetDemo", "declaring an image using Assets"),
new Item("blockdemo", "BlockDemo", "use of blocks to control rendering"),
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java Mon Jan 28 16:11:01 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -84,6 +84,11 @@
RenderQueueImpl queue = new RenderQueueImpl(logger);
+ queue.startComponent("foo");
+ queue.startComponent("bar");
+ queue.endComponent();
+ queue.startComponent("baz");
+
queue.push(rc);
try
@@ -91,9 +96,11 @@
queue.run(writer);
unreachable();
}
- catch (RuntimeException ex)
+ catch (RenderQueueException ex)
{
- assertSame(ex, t);
+ assertSame(ex.getCause(), t);
+
+ assertArraysEqual(ex.getActiveComponentIds(), new String[]{"foo", "baz"});
}
verify();
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java Mon Jan 28 16:11:01 2008
@@ -17,11 +17,9 @@
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
/**
- * A simple, streamlined implementation of {@link java.util.Stack}. The implementation is
- * <em>not</em> threadsafe.
+ * A simple, streamlined implementation of {@link java.util.Stack}. The implementation is <em>not</em> threadsafe.
*
- * @param <E>
- * the type of elements stored in the map
+ * @param <E> the type of elements stored in the map
* @see CollectionFactory#newStack()
*/
public class Stack<E>
@@ -43,8 +41,8 @@
}
/**
- * @param initialSize the initial size of the internal array (which will be expanded as necessary). For
- * best efficiency, set this to the maximum depth of the stack.
+ * @param initialSize the initial size of the internal array (which will be expanded as necessary). For best
+ * efficiency, set this to the maximum depth of the stack.
*/
public Stack(int initialSize)
{
@@ -147,5 +145,21 @@
builder.append("]");
return builder.toString();
+ }
+
+ /**
+ * Returns a snapshot of the current state of the stack as an array of objects. The first object is the deepest in
+ * the stack, the last object is the most shallowest (most recently pushed onto the stack). The returned array may
+ * be manipulated (it is a copy).
+ *
+ * @return the stack as an object array
+ */
+ public Object[] getSnapshot()
+ {
+ Object[] result = new Object[_index + 1];
+
+ System.arraycopy(_items, 0, result, 0, _index + 1);
+
+ return result;
}
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java?rev=616118&r1=616117&r2=616118&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java Mon Jan 28 16:11:01 2008
@@ -59,19 +59,26 @@
assertTrue(stack.isEmpty());
- stack.push("fred");
- assertEquals(stack.peek(), "fred");
+ final String fred = "fred";
+ final String barney = "barney";
+
+ stack.push(fred);
+ assertEquals(stack.peek(), fred);
assertFalse(stack.isEmpty());
- stack.push("barney");
- assertEquals(stack.peek(), "barney");
+ stack.push(barney);
+ assertEquals(stack.peek(), barney);
assertEquals(stack.toString(), "Stack[barney, fred]");
- assertEquals(stack.pop(), "barney");
- assertEquals(stack.peek(), "fred");
+ Object[] snapshot = stack.getSnapshot();
+
+ assertArraysEqual(snapshot, new Object[]{fred, barney});
+
+ assertEquals(stack.pop(), barney);
+ assertEquals(stack.peek(), fred);
- assertEquals(stack.pop(), "fred");
+ assertEquals(stack.pop(), fred);
assertTrue(stack.isEmpty());
}