Update year on copyright
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / 07_Debugging.pod
CommitLineData
d442cc9f 1=head1 NAME
2
3ab6187c 3Catalyst::Manual::Tutorial::07_Debugging - Catalyst Tutorial - Chapter 7: Debugging
3533daff 4
d442cc9f 5
6=head1 OVERVIEW
7
4b4d3884 8This is B<Chapter 7 of 10> for the Catalyst tutorial.
d442cc9f 9
10L<Tutorial Overview|Catalyst::Manual::Tutorial>
11
12=over 4
13
14=item 1
15
3ab6187c 16L<Introduction|Catalyst::Manual::Tutorial::01_Intro>
d442cc9f 17
18=item 2
19
3ab6187c 20L<Catalyst Basics|Catalyst::Manual::Tutorial::02_CatalystBasics>
d442cc9f 21
22=item 3
23
3ab6187c 24L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
d442cc9f 25
26=item 4
27
3ab6187c 28L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>
d442cc9f 29
30=item 5
31
3ab6187c 32L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>
d442cc9f 33
34=item 6
35
3ab6187c 36L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>
d442cc9f 37
38=item 7
39
3ab6187c 40B<07_Debugging>
d442cc9f 41
42=item 8
43
3ab6187c 44L<Testing|Catalyst::Manual::Tutorial::08_Testing>
d442cc9f 45
46=item 9
47
3ab6187c 48L<Advanced CRUD|Catalyst::Manual::Tutorial::09_AdvancedCRUD>
3533daff 49
50=item 10
51
3ab6187c 52L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>
d442cc9f 53
54=back
55
56
57=head1 DESCRIPTION
58
4b4d3884 59This chapter of the tutorial takes a brief look at the primary options
d442cc9f 60available for troubleshooting Catalyst applications.
61
62Note that when it comes to debugging and troubleshooting, there are two
63camps:
64
65=over 4
66
67=item *
68
69Fans of C<log> and C<print> statements embedded in the code.
70
71=item *
72
73Fans of interactive debuggers.
74
75=back
76
77Catalyst is able to easily accommodate both styles of debugging.
78
1390ef0e 79
d442cc9f 80=head1 LOG STATEMENTS
81
1390ef0e 82Folks in the former group can use Catalyst's C<$c-E<gt>log> facility.
83(See L<Catalyst::Log|Catalyst::Log> for more detail.) For example, if
84you add the following code to a controller action method:
d442cc9f 85
86 $c->log->info("Starting the foreach loop here");
87
cae937d8 88 $c->log->debug("Value of \$id is: ".$id);
d442cc9f 89
90Then the Catalyst development server will display your message along
1390ef0e 91with the other debug output. To accomplish the same thing in a TT
92template view use:
d442cc9f 93
8a7c5151 94 [% c.log.debug("This is a test log message") %]
d442cc9f 95
8aa1e01a 96As with many other logging facilities, a method is defined for
ebde193e 97each of the following "logging levels" (in increasing order of
98severity/importance):
99
100 $c->log->debug
101 $c->log->info
102 $c->log->warn
103 $c->log->error
104 $c->log->fatal
105
d442cc9f 106You can also use L<Data::Dumper|Data::Dumper> in both Catalyst code
8c4a5110 107(C<use Data::Dumper; $c-E<gt>log-E<gt>debug("\$var is: ".Dumper($var));)>)
d442cc9f 108and TT templates (C<[% Dumper.dump(book) %]>.
109
1390ef0e 110
d442cc9f 111=head1 RUNNING CATALYST UNDER THE PERL DEBUGGER
112
113Members of the interactive-debugger fan club will also be at home with
114Catalyst applications. One approach to this style of Perl debugging is
115to embed breakpoints in your code. For example, open
116C<lib/MyApp/Controller/Books.pm> in your editor and add the
117C<DB::single=1> line as follows inside the C<list> method (I like to
118"left-justify" my debug statements so I don't forget to remove them, but
119you can obviously indent them if you prefer):
120
ddfbd850 121 sub list :Local {
3533daff 122 # Retrieve the usual Perl OO '$self' for this object. $c is the Catalyst
d442cc9f 123 # 'Context' that's used to 'glue together' the various components
124 # that make up the application
125 my ($self, $c) = @_;
126
127 $DB::single=1;
aa7ff325 128
d442cc9f 129 # Retrieve all of the book records as book model objects and store in the
130 # stash where they can be accessed by the TT template
3b1fa91b 131 $c->stash->{books} = [$c->model('DB::Book')->all];
d442cc9f 132
133 # Set the TT template to use. You will almost always want to do this
134 # in your action methods.
135 $c->stash->{template} = 'books/list.tt2';
136 }
137
138This causes the Perl Debugger to enter "single step mode" when this command is
139encountered (it has no effect when Perl is run without the C<-d> flag).
140
d0496197 141B<NOTE:> The C<DB> here is the Perl Debugger, not the DB model.
142
3b1fa91b 143If you haven't done it already, enable SQL logging as before:
144
145 $ export DBIC_TRACE=1
146
d442cc9f 147To now run the Catalyst development server under the Perl debugger, simply
148prepend C<perl -d> to the front of C<script/myapp_server.pl>:
149
150 $ perl -d script/myapp_server.pl
151
152This will start the interactive debugger and produce output similar to:
153
154 $ perl -d script/myapp_server.pl
155
028b4e1a 156 Loading DB routines from perl5db.pl version 1.3
d442cc9f 157 Editor support available.
158
159 Enter h or `h h' for help, or `man perldebug' for more help.
160
028b4e1a 161 main::(script/myapp_server.pl:16): my $debug = 0;
d442cc9f 162
163 DB<1>
164
165Press the C<c> key and hit C<Enter> to continue executing the Catalyst
166development server under the debugger. Although execution speed will be
167slightly slower than normal, you should soon see the usual Catalyst
168startup debug information.
169
170Now point your browser to L<http://localhost:3000/books/list> and log
171in. Once the breakpoint is encountered in the
172C<MyApp::Controller::list> method, the console session running the
173development server will drop to the Perl debugger prompt:
174
028b4e1a 175 MyApp::Controller::Books::list(/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm:48):
3b1fa91b 176 48: $c->stash->{books} = [$c->model('DB::Book')->all];
d442cc9f 177
178 DB<1>
179
180You now have the full Perl debugger at your disposal. First use the
181C<next> feature by typing C<n> to execute the C<all> method on the Book
182model (C<n> jumps over method/subroutine calls; you can also use C<s> to
183C<single-step> into methods/subroutines):
184
185 DB<1> n
3b1fa91b 186 SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me:
028b4e1a 187 MyApp::Controller::Books::list(/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm:53):
188 53: $c->stash->{template} = 'books/list.tt2';
d442cc9f 189
190 DB<1>
191
192This takes you to the next line of code where the template name is set.
193Notice that because we enabled C<DBIC_TRACE=1> earlier, SQL debug
194output also shows up in the development server debug information.
195
196Next, list the methods available on our C<Book> model:
197
3b1fa91b 198 DB<1> m $c->model('DB::Book')
d442cc9f 199 ()
200 (0+
201 (bool
3b1fa91b 202 __result_class_accessor
028b4e1a 203 __source_handle_accessor
204 _add_alias
3b1fa91b 205 __bool
028b4e1a 206 _build_unique_query
207 _calculate_score
208 _collapse_cond
d442cc9f 209 <lines removed for brevity>
210
211 DB<2>
212
213We can also play with the model directly:
214
3b1fa91b 215 DB<2> x ($c->model('DB::Book')->all)[1]->title
216 SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me:
d442cc9f 217 0 'TCP/IP Illustrated, Volume 1'
218
219This uses the Perl debugger C<x> command to display the title of a book.
220
221Next we inspect the C<books> element of the Catalyst C<stash> (the C<4>
222argument to the C<x> command limits the depth of the dump to 4 levels):
223
224 DB<3> x 4 $c->stash->{books}
225 0 ARRAY(0xa8f3b7c)
d0496197 226 0 MyApp::Model::DB::Book=HASH(0xb8e702c)
d442cc9f 227 '_column_data' => HASH(0xb8e5e2c)
3b1fa91b 228 'created' => '2009-05-08 10:19:46'
d442cc9f 229 'id' => 1
230 'rating' => 5
231 'title' => 'CCSP SNRS Exam Certification Guide'
3b1fa91b 232 'updated' => '2009-05-08 10:19:46'
d442cc9f 233 '_in_storage' => 1
234 <lines removed for brevity>
235
236Then enter the C<c> command to continue processing until the next
237breakpoint is hit (or the application exits):
238
239 DB<4> c
240 SELECT author.id, author.first_name, author.last_name FROM ...
241
242Finally, press C<Ctrl+C> to break out of the development server.
243Because we are running inside the Perl debugger, you will drop to the
3b1fa91b 244debugger prompt.
245
246 ^CCatalyst::Engine::HTTP::run(/usr/local/share/perl/5.10.0/Catalyst/Engine/HTTP.pm:260):
247 260: while ( accept( Remote, $daemon ) ) {
248
249 DB<4>
250
251Finally, press C<q> to exit the debugger and return to your OS
d442cc9f 252shell prompt:
253
254 DB<4> q
255 $
256
257For more information on using the Perl debugger, please see C<perldebug>
3b1fa91b 258and C<perldebtut>. For those daring souls out there, you can dive down
259even deeper into the magical depths of this fine debugger by checking
260out C<perldebguts>.
d442cc9f 261
3b1fa91b 262You can also type C<h> or C<h h> at the debugger prompt to view the
263built-in help screens.
264
265For an excellent book covering all aspects of the Perl debugger, we highly
266recommend reading 'Pro Perl Debugging' by Richard Foley.
267
268Oh yeah, before you forget, be sure to remove the C<DB::single=1> line you
269added above in C<lib/MyApp/Controller/Books.pm>.
d442cc9f 270
271=head1 DEBUGGING MODULES FROM CPAN
272
273Although the techniques discussed above work well for code you are
274writing, what if you want to use print/log/warn messages or set
275breakpoints in code that you have installed from CPAN (or in module that
276ship with Perl)? One helpful approach is to place a copy of the module
277inside the C<lib> directory of your Catalyst project. When Catalyst
278loads, it will load from inside your C<lib> directory first, only
279turning to the global modules if a local copy cannot be found. You can
280then make modifications such as adding a C<$DB::single=1> to the local
281copy of the module without risking the copy in the original location.
282This can also be a great way to "locally override" bugs in modules while
283you wait for a fix on CPAN.
284
285
286Matt Trout has suggested the following shortcut to create a local
287copy of an installed module:
288
289 mkdir -p lib/Module; cp `perldoc -l Module::Name` lib/Module/
290
3b1fa91b 291Note: If you are following along in Debian 5 or Ubuntu, you will
292need to install the C<perl-doc> package to use the C<perldoc> command.
293Use C<sudo aptitude install perl-doc> to do that.
3533daff 294
d442cc9f 295For example, you could make a copy of
296L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
297with the following command:
298
299 mkdir -p lib/Catalyst/Plugin; cp \
300 `perldoc -l Catalyst::Plugin::Authentication` lib/Catalyst/Plugin
301
3533daff 302You can then use the local copy inside your project to place logging
303messages and/or breakpoints for further study of that module.
304
d442cc9f 305B<Note:> Matt has also suggested the following tips for Perl
306debugging:
307
308=over 4
309
310=item *
311
312Check the version of an installed module:
313
d672dfd7 314 perl -M<mod_name> -e 'print "$<mod_name>::VERSION\n"'
d442cc9f 315
316For example:
317
318 $ perl -MCatalyst::Plugin::Authentication -e \
319 'print $Catalyst::Plugin::Authentication::VERSION;'
320 0.07
321
3b1fa91b 322and if you are using bash aliases:
323
324 alias pmver="perl -le '\$m = shift; eval qq(require \$m) \
325 or die qq(module \"\$m\" is not installed\\n); \
326 print \$m->VERSION'"
327
d442cc9f 328=item *
329
330Check if a modules contains a given method:
331
332 perl -MModule::Name -e 'print Module::Name->can("method");'
333
334For example:
335
336 $ perl -MCatalyst::Plugin::Authentication -e \
3533daff 337 'print Catalyst::Plugin::Authentication->can("user");'
d442cc9f 338 CODE(0x9c8db2c)
339
340If the method exists, the Perl C<can> method returns a coderef.
341Otherwise, it returns undef and nothing will be printed.
342
343=back
344
345
1390ef0e 346=head1 TT DEBUGGING
347
348If you run into issues during the rendering of your template, it might
349be helpful to enable TT C<DEBUG> options. You can do this in a Catalyst
350environment by adding a C<DEBUG> line to the C<__PACKAGE__->config>
1edbdee6 351declaration in C<lib/MyApp/View/HTML.pm>:
1390ef0e 352
353 __PACKAGE__->config({
354 TEMPLATE_EXTENSION => '.tt2',
355 DEBUG => 'undef',
356 });
357
358There are a variety of options you can use, such as 'undef', 'all',
359'service', 'context', 'parser' and 'provider'. See
360L<Template::Constants|Template::Constants> for more information
361(remove the C<DEBUG_> portion of the name shown in the TT docs and
362convert to lower case for use inside Catalyst).
363
364B<NOTE:> B<Please be sure to disable TT debug options before continuing
365with the tutorial> (especially the 'undef' option -- leaving this
366enabled will conflict with several of the conventions used by this
367tutorial to leave some variables undefined on purpose).
368
3b1fa91b 369Happy debugging.
1390ef0e 370
d442cc9f 371=head1 AUTHOR
372
373Kennedy Clark, C<hkclark@gmail.com>
374
375Please report any errors, issues or suggestions to the author. The
376most recent version of the Catalyst Tutorial can be found at
59884771 377L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
d442cc9f 378
4768184b 379Copyright 2006-2010, Kennedy Clark, under Creative Commons License
1390ef0e 380(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).