From 25fb019a189096e128203db5083db4c7fcd5abf6 Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Tue, 3 Aug 2010 16:49:24 -0700 Subject: [PATCH] Prepare a test method for throwing Template exceptions. Add code to handle HTTP 304 for visitors. --- lib/WebGUI/Asset.pm | 36 +++++++++++++++++++++++++++--------- lib/WebGUI/Content/Asset.pm | 20 +++++++++++++++++++- t/Asset/dispatch.t | 13 ++++++++++++- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm index a110ab973..0856e669f 100644 --- a/lib/WebGUI/Asset.pm +++ b/lib/WebGUI/Asset.pm @@ -40,6 +40,7 @@ use WebGUI::ProgressBar; use WebGUI::Search::Index; use WebGUI::TabForm; use WebGUI::Utility; +use WebGUI::PassiveAnalytics::Logging; =head1 NAME @@ -564,27 +565,44 @@ sub definition { Based on the URL and query parameters in the current request, call internal methods like www_view, www_edit, etc. If no query parameter is present, then it returns the output -from the view method. - -When this method returns undef, it means that the requested URL does not match this Asset's -URL. +from the www_view method. If the requested method does not exist in the object, it returns +the output from the www_view method. =head3 $fragment Any leftover part of the requested URL. +=head3 _view + +This option should only be used internally, when trying to call the view method when +the requested method has failed. + =cut sub dispatch { - my ($self, $fragment) = @_; + my ($self, $fragment, $_view) = @_; return undef if defined $fragment; + my $session = $self->session; my $state = $self->get('state'); ##Only allow interaction with assets in certain states - return if $state ne 'published' && $state ne 'archived' && !$self->session->var->isAdminOn; - my $func = $self->session->form->param('func') || 'view'; - my $sub = $self->can('www_'.$func) || $self->can('www_view'); + return if $state ne 'published' && $state ne 'archived' && !$session->var->isAdminOn; + my $func = $session->form->param('func') || 'view'; + $func = 'view' if $_view; + my $viewing = $func eq 'view' ? 1 : 0; + my $sub = $self->can('www_'.$func); + if (!$sub && $func ne 'view') { + $sub = $self->can('www_view'); + $viewing = 1; + } return undef unless $sub; - my $output = $sub->(); + my $output = eval { $sub->(); }; + if (my $e = Exception::Class->caught('WebGUI::Error::ObjectNotFound::Template')) { + $session->log->error(sprintf "%s templateId: %s assetId: %s", $e->error, $e->templateId, $e->assetId); + } + elsif ($@) { + $session->errorHandler->warn("Couldn't call method www_".$func." on asset for url: ".$session->url->getRequestedUrl." Root cause: ".$@); + die $@; + } return $output; } diff --git a/lib/WebGUI/Content/Asset.pm b/lib/WebGUI/Content/Asset.pm index 16b53328c..6f9770c85 100644 --- a/lib/WebGUI/Content/Asset.pm +++ b/lib/WebGUI/Content/Asset.pm @@ -66,9 +66,27 @@ sub dispatch { my $permutations = getUrlPermutations($assetUrl); foreach my $url (@{ $permutations }) { if (my $asset = getAsset($session, $url)) { + # display from cache if page hasn't been modified. + if ($session->user->isVisitor + && !$session->http->ifModifiedSince($asset->getContentLastModified, $session->setting->get('maxCacheTimeout'))) { + $session->http->setStatus("304","Content Not Modified"); + $session->http->sendHeader; + $session->close; + return "chunked"; + } + my $fragment = $assetUrl; $fragment =~ s/$url//; - my $output = $asset->dispatch($fragment); + my $output = eval { $asset->dispatch($fragment); }; + if ($@) { + $session->errorHandler->warn("Couldn't call method ".$method." on asset for url: ".$session->url->getRequestedUrl." Root cause: ".$@); + if ($method ne "view") { + $output = tryAssetMethod($session,$asset,'view'); + } else { + # fatals return chunked + $output = 'chunked'; + } + } return $output if defined $output; } } diff --git a/t/Asset/dispatch.t b/t/Asset/dispatch.t index a7e216245..0ad6aa247 100644 --- a/t/Asset/dispatch.t +++ b/t/Asset/dispatch.t @@ -30,6 +30,8 @@ BEGIN { package WebGUI::Asset::TestDispatch; +use WebGUI::Asset; +use WebGUI::Exception; our @ISA = ('WebGUI::Asset'); # Override dispatch to handle special /foo URL @@ -55,6 +57,15 @@ sub www_alsoView { return; } +sub www_brokenTemplate { + my $self = shift; + WebGUI::Error::ObjectNotFound::Template->throw( + error => qq{Template not found}, + templateId => "This is a GUID", + assetId => $self->getId, + ); +} + package main; my $tag = WebGUI::VersionTag->getWorking( $session ); @@ -100,7 +111,7 @@ is( $td->dispatch, "www_view", "requests for non-existant methods return www_vie $session->request->setup_body( { func => 'alsoView', } ); -is( $td->dispatch, "www_view", "if a query method return undef, view is still returned" ); +is( $td->dispatch, "www_view", "if a query method returns undef, view is still returned" ); $session->request->setup_body( { } ); $output = $td->dispatch( '/not-foo' );