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