[Catalyst] [OT] Trouble with Chained Actions and Redirects?

Robert 'phaylon' Sedlacek phaylon at dunkelheit.at
Tue Sep 19 18:12:09 CEST 2006


John Napiorkowski said:
> I have a lot of programmers with experience writing
> mod_perl apps and for them (and me) we are used to the
> idea that you can end processing with a location
> header and returning the redirect http status code.

<enter yoda quote here>

> There is no equally obvious method to end processing
> in Catalyst, since the detach method is not documented
> that way and the word itself does not give me the idea
> to use it for that purpose.

Well, that part of documentation has been added to Catalyst.pm recently.

> Also I think it's intuitive to think that redirect
> would function as a end to processing, which is how I
> got into this trouble in the first place.  I'm not
> saying that Catalyst should do that, because I can see
> the very valid reasons why it doesn't, I'm just saying
> that in the absence of direction my instincts
> developed from writing CGI and mod_perl apps would
> lead me to think that a redirect call would function
> as a end to the processing.  When it didn't it caused
> confusion and misunderstanding.  I am guessing I am
> not the only one confused about this.

I think the main misunderstanding is the way Catalyst works. It is not
like a mod_perl handler or CGI script in that you just say "I'm finished."
Because Catalyst is supposed to do your finishing works (headers, outputs,
session sync, etc.). Therefore the wording in C:Response

  Causes the response to redirect to the specified URL.

can be misleading if you're standing at the POV that you immediately send
a response, and not just prepare it.

> I'd be happy to offer a small POD patch to the
> redirect and detach functions to document that
> redirect doesn't actually redirect until you reach the
> endpoint in your catalyst chain or sequence of actions
> and that this is a good thing because it give you
> finer control.

++ for that.

> Also that $c->detach is the catalyst way to end
> processing a chain right away and fills the role that
> "return HTTP_STATUS_CODE" does for mod_perl apps except
> it's better because it also you to do some cleanup and
> finalization if you need to.

Well, no. detach() really just returns and lets Catalyst look for an end
action and then start the finalization. To prepare your response, you'd
act on the $c->response object, just like with redirect. In Catalyst, you
don't return a stream of headers and data yourself, but you build up your
response object during the execution of the request, and Cat will care for
returning it to the user.

I know, the difference seems minimal, but I already see people asking why
detach doesn't accept status values, if we're stating it exactly like that
:)

> I guess another way to handle this is to write your
> own action to handle redirects as I have for handling
> not found and other error types.  I have a controller
> for this: $c->detach("/errors/not_found", [$errmsg])
> which I use for this purpose.  I could create a
> $c->detach("/http/redirect", [$url]) to handle this
> instead of using the catalyst built in.

That would be a possibility. I myself usually just detach to the specific
actions doing the redirect then. I have most redirects behind actions that
change something, so mostly after POST requests. Then I'd have
(pseudo-perl)

  if ($this_was_submitted) {
      put_stuff_in_the_stash();
      $c->detach('do_store_stuff_in_db');
  }

To be honest, it largely depends on how you build your application and
your control flow. Catalysts big advantage is that it can fit flexibly in
many designs, so there's no true way. Do whatever makes sense, is
read-/maintainable and gives an elegant feeling to you and your
developers.

if you really need this often, a MyApp plugin, a controller base class or
any other way to write this to easily integrate it into your apps might
fit what you're looking for.





More information about the Catalyst mailing list