[Agavi-Users] Handling errors

0 views
Skip to first unread message

Van Daele, Koen

unread,
Jun 27, 2007, 6:18:49 AM6/27/07
to Agavi Users Mailing List
Hi all,

I'm trying to decide how to go about handling crud errors. From the IRC
logs I've gathered that the best approach would be to have:
- An InputView
- An ErrorView that uses the InputTemplate
- A SuccessView that redirects to

The problem I'm having is that there are different types of errors. E.g
take a simple Book.Edit action. The first possible error is a user
trying to edit a book that doesn't exist (should return a 404 or a
'sorry, this book doesn't exist' page. The second type of error is a
user entering incorrect data (a validation error) that show the input
template again. A third possible error might be that there's a
concurreny issue (should e.g. tell the user to re-edit the record or
should ask them if they're sure they want to overwrite user z's edit).

Do you use different Error views (eg. InputErrorView, NotFoundErrorView,
ConcurrencyErrorView)? Or do you set an attribute in the action and then
let the error view decide what to do? Are there other options?

Greetings,
Koen

_______________________________________________
users mailing list
us...@lists.agavi.org
http://lists.agavi.org/mailman/listinfo/users

David Zülke

unread,
Jun 27, 2007, 6:42:48 AM6/27/07
to Agavi Users Mailing List
Hi Koen,

I think multiple Views are the way to go here. Your NotFoundErrorView
could then forward to the 404 action, for example, so you don't have
too much duplicate code. If your 404 action is empty, i.e. just a
view (which it should be), then you could also return array
(AgaviConfig::get('actions.404_module'), AgaviConfig::get('actions.
404_action')) from the action to make agavi use that view instead of
one related to the action itself. You can talk to the validation
manager (available from the container) inside handleError() to find
out which validator failed, and then return the appropriate view name.


Hope that helps,

David

Van Daele, Koen

unread,
Jun 27, 2007, 7:25:59 AM6/27/07
to Agavi Users Mailing List
Ok, thx for the feedback.

Returning the global 404 view does seem better than having a 404View per action (since almost every action could have a itemNotFound error.

Koen

> -----Oorspronkelijk bericht-----
> Van: users-...@lists.agavi.org
> [mailto:users-...@lists.agavi.org] Namens David Zülke
> Verzonden: woensdag 27 juni 2007 12:43
> Aan: Agavi Users Mailing List
> Onderwerp: Re: [Agavi-Users] Handling errors

Noah Fontes

unread,
Jun 27, 2007, 5:44:08 PM6/27/07
to Agavi Users Mailing List
Afternoon,

Have you taken a look at Veikko's CMS application? He uses a pretty unique
method to determine whether some object is valid. What he's done is set up a
routing callback that checks the id parameter of the request data and grabs
the correct item from the DB and sends it to Request or returns false if it
doesn't exist.

I'm not sure how 'correct' this is (it'd have to be in your global namespace,
and if you have to do any manipulation/validation of request data besides
checking to see if it exists in the database, this probably isn't the way to
go), but it might be worth a try.

The major upside to this is that you can specify the same routing callback to
check/validate multiple routes -- plus it forwards to the 404 action by
default upon returning false in the method.

I definitely like the idea of setting the proper view in handleError() too
(obviously Veikko's idea is only for the 404 part :). +1 for that as well.

Regards,

Noah

--
Noah Fontes
Cynigram Network Administrator
im...@cynigram.com

David Zülke

unread,
Jun 27, 2007, 5:56:34 PM6/27/07
to Agavi Users Mailing List
The problem I see with this is that it happens too early, outside the
normal validation process. OTOH, it's probably justified as every
request goes to such an "object", hence a "validation" in a routing
callback could very well be justified.

A good example of a situation where, in my opinion, validating
something in a routing callback is okay is when you have a service
that allows people to register their own subdomains:

<route name="subdomain" pattern="^(userdomain:[^.]+).myservice.com$"
callback="UserSubdomainRoutingCallback" />

because otherwise, you would have to validate the subdomain in every
single action, and maybe even take other measures (such as store the
subdomain somewhere for later use, gather info about that account,
and so on).


David

Shoan Motwani

unread,
Jul 3, 2007, 8:51:46 AM7/3/07
to Agavi Users Mailing List
We have a similar situation in our project. We need to validate
whether the logged in user can edit/delete a record. I am thinking
that a callback in the routing containing the id of the record
( www.example.org/edit/123) would be the best place to validate
whether the user can actually mess with the record.

Is there a better way?

Peace,
Shoan.

David Zülke

unread,
Jul 3, 2007, 9:22:32 AM7/3/07
to Agavi Users Mailing List
That's security. I can see how the vanilla security system cannot
handle this; I recommend extending SecurityFilter so it calls a
checkPermissions() method or something on the action.


HTH,

David

Van Daele, Koen

unread,
Jul 4, 2007, 2:46:15 AM7/4/07
to Agavi Users Mailing List
That's something I was thinking about a while back. Wouldn't it be nice to have a default method for that like the validate() methods (where you have different levels of control: validate.xml, registerValidators() and the validate() method). Every once in a while I see people ask something similar (basically check if the user has the edit credential for a certain record. You do indeed need a checkPermissions() or similar method for that. I think it might be usefull as a default feature of the security system. If it exists for validation I think it can exist for security too.

Koen

> -----Oorspronkelijk bericht-----
> Van: users-...@lists.agavi.org
> [mailto:users-...@lists.agavi.org] Namens David Zülke

> Verzonden: dinsdag 3 juli 2007 15:23

Veikko Mäkinen

unread,
Jul 4, 2007, 4:03:05 AM7/4/07
to Agavi Users Mailing List

You can also do this by extending AgaviRbacSecurityUser and, in your
overriding loadDefinitions, load user's credentials to edit/delete
records (for example store all record ids the user can edit as
'record.edit.[id]' credentials.

Then:

//PageModifyAction::getCredentials()

//admin group can modify all pages
$cred = array('admin.page.modify');

if ($page->getWriteAccessRoleId() !== null) {
// page.write.[id] is given to the user in MyRbacUser::loadDefitions
// if the user's group has modify access to the page
$cred[] = 'page.write.' . $page->getId();
}

return array($cred);

-veikko

P.S. Top posting makes it harder to follow these threads and at least
every one could clean up the reply before sending (footers and such)

Van Daele, Koen

unread,
Jul 4, 2007, 5:01:29 AM7/4/07
to Agavi Users Mailing List

> -----Oorspronkelijk bericht-----
> Van: users-...@lists.agavi.org
> [mailto:users-...@lists.agavi.org] Namens Veikko Mäkinen
> Verzonden: woensdag 4 juli 2007 10:03

I can see this working as long as the number of records is rather small, but in the case where I might need to implement this I'm talking about some 50.000-100.000 records where one user might have 'record.edit.[id]' for some 10.000-20.000 records, so loading all that data as rbac permissions seems a bit much.

Koen

David Zülke

unread,
Jul 4, 2007, 7:56:40 AM7/4/07
to Agavi Users Mailing List
Am 04.07.2007 um 11:01 schrieb Van Daele, Koen:

>> You can also do this by extending AgaviRbacSecurityUser and,
>> in your overriding loadDefinitions, load user's credentials
>> to edit/delete records (for example store all record ids the
>> user can edit as 'record.edit.[id]' credentials.
>>
>>

>> -veikko


>>
>
> I can see this working as long as the number of records is rather
> small, but in the case where I might need to implement this I'm
> talking about some 50.000-100.000 records where one user might have
> 'record.edit.[id]' for some 10.000-20.000 records, so loading all
> that data as rbac permissions seems a bit much.
>
> Koen

That's exactly right, it quickly gets out of hand with many records.
As for the suggestion to implement such a thing as the default, I
will look into this as the exact same requirement has come up here at
the company where I'm currently doing consulting.

Cheers,

David

Reply all
Reply to author
Forward
0 new messages