+sub handle_error {
+ my ($self, $err) = @_;
+ die $err if $self->{'_handling_error'};
+ local @{ $self }{'_handling_error', '_recurse' } = (1, 0); # allow for this next step - even if we hit a recurse error
+ $self->stash->{'error_step'} = $self->current_step;
+ $self->stash->{'error'} = $err;
+ eval {
+ my $step = $self->error_step;
+ $self->morph($step); # let steps be in external modules
+ $self->run_hook('run_step', $step) && $self->unmorph($step);
+ };
+ die $@ if $@ && $@ ne "Long Jump\n";
+}
+
+###---------------------###
+# read only accessors
+
+sub allow_morph { $_[0]->{'allow_morph'} }
+sub auth_args { $_[0]->{'auth_args'} }
+sub charset { $_[0]->{'charset'} || '' }
+sub conf_args { $_[0]->{'conf_args'} }
+sub conf_die_on_fail { $_[0]->{'conf_die_on_fail'} || ! defined $_[0]->{'conf_die_on_fail'} }
+sub conf_path { $_[0]->{'conf_path'} || $_[0]->base_dir_abs }
+sub conf_validation { $_[0]->{'conf_validation'} }
+sub default_step { $_[0]->{'default_step'} || 'main' }
+sub error_step { $_[0]->{'error_step'} || '__error' }
+sub fill_args { $_[0]->{'fill_args'} }
+sub forbidden_step { $_[0]->{'forbidden_step'} || '__forbidden' }
+sub form_name { $_[0]->{'form_name'} || 'theform' }
+sub history { $_[0]->{'history'} ||= [] }
+sub js_step { $_[0]->{'js_step'} || 'js' }
+sub login_step { $_[0]->{'login_step'} || '__login' }
+sub mimetype { $_[0]->{'mimetype'} || 'text/html' }
+sub path_info { defined $_[0]->{'path_info'} ? $_[0]->{'path_info'} : $_[0]->cgix->env->{'PATH_INFO'} || '' }
+sub path_info_map_base { $_[0]->{'path_info_map_base'} ||[[qr{/(\w+)}, $_[0]->step_key]] }
+sub recurse_limit { $_[0]->{'recurse_limit'} || 15 }
+sub script_name { defined $_[0]->{'script_name'} ? $_[0]->{'script_name'} : $_[0]->cgix->env->{'SCRIPT_NAME'} || $0 }
+sub stash { $_[0]->{'stash'} ||= {} }
+sub step_key { $_[0]->{'step_key'} || 'step' }
+sub template_args { $_[0]->{'template_args'} }
+sub template_path { $_[0]->{'template_path'} || $_[0]->base_dir_abs }
+sub val_args { $_[0]->{'val_args'} }
+sub val_path { $_[0]->{'val_path'} || $_[0]->template_path }
+
+sub conf_obj {
+ my $self = shift;
+ return $self->{'conf_obj'} || do {
+ my $args = $self->conf_args || {};
+ $args->{'paths'} ||= $self->conf_path;
+ $args->{'directive'} ||= 'MERGE';
+ require CGI::Ex::Conf;
+ CGI::Ex::Conf->new($args);
+ };