<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/undo_failed.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -8,19 +8,32 @@ class Admin::UndoItemsController &lt; Admin::BaseController
 
   def undo
     item = UndoItem.find(params[:id])
-    object = item.process!
+    begin
+      object = item.process!
 
-    respond_to do |format|
-      format.html {
-        flash[:notice] = item.complete_description
-        redirect_to(:back)
-      }
-      format.json {
-        render :json =&gt; {
-          :message =&gt; item.complete_description,
-          :obj     =&gt; object
+      respond_to do |format|
+        format.html {
+          flash[:notice] = item.complete_description
+          redirect_to(:back)
         }
-      }
+        format.json {
+          render :json =&gt; {
+            :message =&gt; item.complete_description,
+            :obj     =&gt; object
+          }
+        }
+      end
+    rescue UndoFailed
+      msg = &quot;Could not undo, would result in an invalid state (i.e. a comment with no post)&quot;
+      respond_to do |format|
+        format.html {
+          flash[:notice] = msg
+          redirect_to(:back)
+        }
+        format.json {
+          render :json =&gt; { :message =&gt; msg }
+        }
+      end
     end
   end
 end</diff>
      <filename>app/controllers/admin/undo_items_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,11 @@
 class DeleteCommentUndo &lt; UndoItem
   def process!
-    raise('Comment already exists') if Comment.find_by_id(loaded_data.delete('id').to_i)
+    raise(UndoFailed) if Comment.find_by_id(loaded_data.delete('id').to_i)
 
     comment = nil
     transaction do
-      comment = Comment.create!(loaded_data)
+      comment = Comment.create(loaded_data)
+      raise UndoFailed if comment.new_record?
       self.destroy
     end
     comment</diff>
      <filename>app/models/delete_comment_undo.rb</filename>
    </modified>
    <modified>
      <diff>@@ -48,4 +48,37 @@ describe Admin::UndoItemsController do
     it(&quot;renders json&quot;)       { do_post; response.should have_text(/hello/) }
     it(&quot;processes the item&quot;) { @item.should_receive(:process!); do_post } 
   end
+
+  describe 'handling POST to undo with invalid undo item' do
+    before do
+      @item = mock_model(UndoItem)
+      @item.stub!(:process!).and_raise(UndoFailed)
+      UndoItem.stub!(:find).and_return(@item)
+    end
+
+    def do_post
+      request.env[&quot;HTTP_REFERER&quot;] = &quot;/bogus&quot;
+      session[:logged_in] = true
+      post :undo, :id =&gt; 1
+    end
+    
+    it(&quot;redirects back&quot;)             { do_post; response.should redirect_to(&quot;/bogus&quot;) }
+    it(&quot;stores notice in the flash&quot;) { do_post; flash[:notice].should_not be_nil }
+  end
+
+  describe 'handling POST to undo with invalid undo item accepting JSON' do
+    before do
+      @item = mock_model(UndoItem)
+      @item.stub!(:process!).and_raise(UndoFailed)
+      UndoItem.stub!(:find).and_return(@item)
+    end
+
+    def do_post
+      request.env[&quot;HTTP_REFERER&quot;] = &quot;/bogus&quot;
+      session[:logged_in] = true
+      post :undo, :id =&gt; 1, :format =&gt; 'json'
+    end
+    
+    it(&quot;renders json&quot;) { do_post; response.should have_text(/message/) }
+  end
 end</diff>
      <filename>spec/controllers/admin/undo_items_controller_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@ describe DeleteCommentUndo do
       item.stub!(:transaction).and_yield
       item.stub!(:destroy)
 
-      Comment.should_receive(:create!).with('a' =&gt; 'b')
+      Comment.should_receive(:create).with('a' =&gt; 'b').and_return(mock(&quot;comment&quot;, :new_record? =&gt; false))
       item.process!
     end
   end
@@ -18,7 +18,17 @@ describe DeleteCommentUndo do
     it 'raises' do
       pending(&quot;figure out why should_raise doesn't work&quot;)
       Comment.stub!(:find_by_id).and_return(Object.new)
-      lambda { DeleteCommentUndo.process! }.should_raise('Comment already exists')
+      lambda { DeleteCommentUndo.process! }.should_raise(UndoFailed)
+    end
+  end
+
+  describe '#process! with invalid comment' do
+    it 'raises' do
+      pending(&quot;figure out why should_raise doesn't work&quot;)
+      Comment.stub!(:find_by_id).and_return(nil)
+
+      Comment.should_receive(:create).with('a' =&gt; 'b').and_return(mock(&quot;comment&quot;, :new_record? =&gt; true))
+      lambda { DeleteCommentUndo.process! }.should_raise(UndoFailed)
     end
   end
 </diff>
      <filename>spec/models/delete_comment_undo_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>90dc474b93942b40d4a55140ed63517598262951</id>
    </parent>
  </parents>
  <author>
    <name>Xavier Shay</name>
    <email>xavier@rhnh.net</email>
  </author>
  <url>http://github.com/xaviershay/enki/commit/b28f2fc710dd2997bb400bdeb24f0099b429196a</url>
  <id>b28f2fc710dd2997bb400bdeb24f0099b429196a</id>
  <committed-date>2008-04-28T01:37:19-07:00</committed-date>
  <authored-date>2008-04-28T01:37:19-07:00</authored-date>
  <message>Don't blow up on invalid undos</message>
  <tree>3c1cd40e7940236698b1294ce1f7092ba0b344a0</tree>
  <committer>
    <name>Xavier Shay</name>
    <email>xavier@rhnh.net</email>
  </committer>
</commit>
