Index: trunk/PS-IPP-Config/lib/PS/IPP/Config.pm
===================================================================
--- trunk/PS-IPP-Config/lib/PS/IPP/Config.pm	(revision 21320)
+++ trunk/PS-IPP-Config/lib/PS/IPP/Config.pm	(revision 23185)
@@ -71,5 +71,5 @@
     unless (defined $class) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -85,5 +85,5 @@
     unless (open $file, $name) {
         carp "Unable to open ipprc file $name: $!";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
     my @contents = <$file>;        # Contents of the ipprc file
@@ -95,5 +95,5 @@
     unless (defined $path) {
         carp "PATH is not set in $name\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -112,8 +112,8 @@
     bless $self, $class;
 
-    $self->load_site();
-    $self->load_system();
-
-    $self->define_camera($camera) if defined $camera;
+    $self->load_site() or return undef;
+    $self->load_system() or return undef;
+
+    ( $self->define_camera($camera) or return undef ) if defined $camera;
 
     return $self;
@@ -148,5 +148,5 @@
                 unless ($found) {
                     carp "Unable to find camera configuration file $filename\n";
-                    exit($PS_EXIT_CONFIG_ERROR);
+                    return undef;
                 }
             }
@@ -158,5 +158,5 @@
 
     carp "Unable to find configuration file: $filename";
-    exit($PS_EXIT_CONFIG_ERROR);
+    return undef;
 }
 
@@ -170,5 +170,5 @@
     unless (defined $self) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -176,8 +176,9 @@
     unless (defined $filename) {
         carp "Unable to find site configuration file\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
     my $realfile = $self->_find_config($filename); # Resolved filename, after hunting the PATH
+    ( carp "Unable to find site configuration" and return undef ) unless defined $realfile;
 
     # Read the file
@@ -185,5 +186,5 @@
     unless (open $file, $realfile) {
         carp "Unable to open site configuration file $realfile: $!";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -194,5 +195,5 @@
     unless (defined $self->{_siteConfig}) {
         carp "Failure to parse the site configuration file $realfile";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -207,5 +208,5 @@
     unless (defined $self) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -213,8 +214,9 @@
     unless (defined $filename) {
         carp "Unable to find system configuration file\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
     my $realfile = $self->_find_config($filename); # Resolved filename, after hunting the PATH
+    ( carp "Unable to find system configuration" and return undef ) unless defined $realfile;
 
     # Read the file
@@ -222,5 +224,5 @@
     unless (open $file, $realfile) {
         carp "Unable to open system configuration file $realfile: $!";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
     my @contents = <$file>;
@@ -230,5 +232,5 @@
     unless (defined $self->{_systemConfig}) {
         carp "Failure to define system configuration";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -244,5 +246,5 @@
     unless (defined $self and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -251,8 +253,9 @@
     unless (defined $filename) {
         carp "Unable to find configuration file for camera $name\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
     my $realfile = $self->_find_config($filename); # Resolved filename, after hunting the PATH
+    ( carp "Unable to find camera configuration" and return undef ) unless defined $realfile;
 
     # Read the file
@@ -260,5 +263,5 @@
     unless (open $file, $realfile) {
         carp "Unable to open camera configuration file $realfile: $!";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
     my @contents = <$file>;
@@ -269,5 +272,5 @@
     unless (defined $self->{camera}) {
         carp "Failure to define camera";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -326,5 +329,5 @@
     unless (defined $self and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -333,5 +336,5 @@
     unless (defined $pathname) {
         carp "Unable to find datapath $name\n" ;
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -340,5 +343,5 @@
 
 # convert the database name and the table ID to a image source id
-sub source_id 
+sub source_id
 {
     my $self = shift;
@@ -351,8 +354,8 @@
     my $admindb = "ippadmin";
 
-    die "dbserver not defined in configuration" unless defined($dbserver);
-    die "dbuser not defined in configuration" unless defined($dbuser);
-    die "dbpassword not defined in configuration" unless defined($dbpassword);
-    die "dbname not defined in configuration" unless defined($dbname);
+    ( carp "dbserver not defined in configuration"  and return undef ) unless defined($dbserver);
+    ( carp "dbuser not defined in configuration"  and return undef ) unless defined($dbuser);
+    ( carp "dbpassword not defined in configuration"  and return undef ) unless defined($dbpassword);
+    ( carp "dbname not defined in configuration"  and return undef ) unless defined($dbname);
 
     my $dsn = "DBI:mysql:host=$dbserver;database=$admindb";
@@ -363,5 +366,5 @@
     $stmt->execute();
     my $ref = $stmt->fetchrow_hashref();
-    die "ippdb $dbname not found" unless ($ref);
+    ( carp "ippdb $dbname not found" and return undef ) unless ($ref);
 
     my $proj_id = $ref->{proj_id};
@@ -382,5 +385,5 @@
     if ($@) {
         carp "Can't find Nebulous::Client.";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -390,11 +393,11 @@
     unless (defined $server) {
         carp "Unable to find NEB_SERVER in camera configuration file.";
-        exit($PS_EXIT_CONFIG_ERROR);
-    }
-
-    my $neb = Nebulous::Client->new( proxy => $server );
-    unless (defined $neb) {
+        return undef;
+    }
+
+    my $neb = eval { Nebulous::Client->new( proxy => $server ); };
+    if ($@ or not defined $neb) {
         carp "Unable to find NEB_SERVER in camera configuration file.";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -415,28 +418,30 @@
     if ($scheme) {
         $scheme = lc($scheme);
-	# print "scheme: $scheme\n";
+        # print "scheme: $scheme\n";
 
         if ($scheme eq 'neb') {
-            $self->_neb_start();
+            $self->_neb_start() or ( carp "Can't start Nebulous" and return undef );
             my $neb = $self->{nebulous}; # Nebulous handle
             if ($create_if_doesnt_exist) {
-                unless ($neb->stat( $name )) {
-		    # print "entry $name not found, creating...\n";
-                    my $uri = $neb->create( $name );
-                    unless(defined $uri) {
+                my $status = eval { $neb->stat( $name ); };
+                ( carp "Unable to stat Nebulous handle $name" and return undef ) if $@;
+                unless ($status) {
+                    # print "entry $name not found, creating...\n";
+                    my $uri = eval { $neb->create( $name ); };
+                    if ($@ or not defined $uri) {
                         carp "unable to instantiate $name.";
-                        exit($PS_EXIT_DATA_ERROR);
+                        return undef;
                     }
                     my $path = URI->new( $uri )->path;
-		    # print "created path: $path\n";
+                    # print "created path: $path\n";
                     return $path;
                 }
             }
-	    my $path = $neb->find( $name );
-	    if (not defined $path) { 
-		carp "neb entry $name not found, not created\n"; 
-		exit($PS_EXIT_DATA_ERROR);
-	    } 
-	    # print "found path: $path\n";
+            my $path = eval { $neb->find( $name ); };
+            if ($@ or not defined $path) {
+                carp "neb entry $name not found, not created\n";
+                return undef;
+            }
+            # print "found path: $path\n";
             return $path;
         }
@@ -444,6 +449,6 @@
         if ($scheme eq 'path' or $scheme eq 'file') {
             # guaranteed to have a scheme (path:// or file://)
-            $name = $self->convert_filename_absolute( $name );
-	    # print "resolved path to $name\n";
+            $name = $self->convert_filename_absolute( $name ) or return undef;
+            # print "resolved path to $name\n";
         }
     }
@@ -454,12 +459,13 @@
         if (! -e $dir) {
             my $rc = system "mkdir -p $dir";
-            die "failed to create directory for $name" unless (!$rc);
+            ( carp "failed to create directory for $name" and return undef ) unless (!$rc);
         } elsif (! -d $dir ) {
-            die "parent for $name exists and is not a directory";
-        }
-
-        open F, ">$name" or die "failed to create $name";
+            carp "parent for $name exists and is not a directory";
+            return undef;
+        }
+
+        open F, ">$name" or ( carp "failed to create $name" and return undef );
         close F;
-	# print "created target $name\n";
+        # print "created target $name\n";
     }
 
@@ -473,5 +479,5 @@
     my $name = shift;                # File name to check
 
-    $self->file_prepare( $name );
+    $self->file_prepare( $name ) or return undef;
 
     my $scheme = file_scheme($name); # The scheme, e.g., file://, path://
@@ -479,10 +485,15 @@
         $scheme = lc($scheme);
         if ($scheme eq 'neb') {
-            $self->_neb_start();
-            return $self->{nebulous}->open_create( $name );
+            $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+            my $fh = eval { $self->{nebulous}->open_create( $name ); };
+            if ($@ or not defined $fh) {
+                carp "Unable to open/create Nebulous handle $name";
+                return undef;
+            }
+            return $fh;
         }
         if ($scheme eq 'path' or $scheme eq 'file') {
             # guaranteed to have a scheme (path:// or file://)
-            $name = $self->convert_filename_absolute( $name );
+            $name = $self->convert_filename_absolute( $name ) or return undef;
         }
     }
@@ -490,5 +501,5 @@
     if (-f $name) {
         carp "Unable to create file $name --- file exists.";
-        exit($PS_EXIT_SYS_ERROR);
+        return undef;
     }
 
@@ -496,5 +507,5 @@
     unless (open $fh, '>', $name) {
         carp "Unable to create file $name --- $!";
-        exit($PS_EXIT_SYS_ERROR);
+        return undef;
     }
     return $fh;
@@ -507,5 +518,5 @@
     my $name = shift;                # File name to check
 
-    $self->file_prepare( $name );
+    $self->file_prepare( $name ) or return undef;
 
     my $scheme = file_scheme($name); # The scheme, e.g., file://, path://
@@ -513,10 +524,15 @@
         $scheme = lc($scheme);
         if ($scheme eq 'neb') {
-            $self->_neb_start();
-            return $self->{nebulous}->open_create( $name );
+            $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+            my $fh = eval { $self->{nebulous}->open_create( $name ) };
+            if ($@ or not defined $fh) {
+                carp "Unable to open/create Nebulous handle $name";
+                return undef;
+            }
+            return $fh;
         }
         if ($scheme eq 'path' or $scheme eq 'file') {
             # guaranteed to have a scheme (path:// or file://)
-            $name = $self->convert_filename_absolute( $name );
+            $name = $self->convert_filename_absolute( $name ) or return undef;
         }
     }
@@ -525,5 +541,5 @@
     unless (open $fh, '>>', $name) {
         carp "Unable to create file $name --- $!";
-        exit($PS_EXIT_SYS_ERROR);
+        return undef;
     }
     return $fh;
@@ -536,10 +552,14 @@
     my $name = shift;                # File name to check
 
-    $self->file_prepare( $name );
+    $self->file_prepare( $name ) or return undef;
 
     my $scheme = file_scheme($name); # The scheme, e.g., file://, path://
     if (defined $scheme and lc($scheme) eq 'neb') {
-        $self->_neb_start();
-        $name = $self->{nebulous}->create( $name );
+        $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+        $name = eval { $self->{nebulous}->create( $name ) };
+        if ($@ or not defined $name) {
+            carp "Unable to create Nebulous handle $name";
+            return undef;
+        }
     }
 
@@ -555,6 +575,8 @@
     my $scheme = file_scheme($name); # The scheme, e.g., file://, path://
     if (defined $scheme and lc($scheme) eq 'neb') {
-        $self->_neb_start();
-        return (defined $self->{nebulous}->find_instances( $name ) ? 1 : 0);
+        $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+        my $found = eval { $self->{nebulous}->find_instances( $name ); };
+        ( carp "Unable to find instances of Nebulous handle $name" and return undef ) if $@;
+        return (defined $found ? 1 : 0);
     }
 
@@ -569,16 +591,19 @@
     my $target = shift;                # Name of target file
 
-    $self->file_prepare( $target );
+    $self->file_prepare( $target ) or return undef;
 
     my $scheme = file_scheme($target); # The scheme, e.g., file://, path://
     if (defined $scheme and lc($scheme) eq 'neb') {
-        $self->_neb_start();
-        $target = $self->{nebulous}->create( $target );
+        $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+        $target = eval { $self->{nebulous}->create( $target ); };
+        if ($@ or not defined $target) {
+            carp "Unable to create Nebulous handle";
+            return undef;
+        }
     }
     $target = $self->file_resolve( $target );
     $source = $self->file_resolve( $source );
 
-    system("cp $source $target") == 0 or (carp "Can't copy file $source to $target." and
-                                          exit($PS_EXIT_DATA_ERROR));
+    system("cp $source $target") == 0 or ( carp "Can't copy file $source to $target." and return undef );
     return 1;
 }
@@ -593,5 +618,5 @@
     my $preserve = shift;
 
-    die "pathname must be defined" unless ($pathname);
+    ( carp "pathname must be defined" and return undef ) unless ($pathname);
 
     my $fileRef;
@@ -602,7 +627,7 @@
 
     if ($preserve) {
-        # we want to keep the file just create it in the current directory 
+        # we want to keep the file just create it in the current directory
         $fileName = "./$base";
-        open $fileRef, ">$fileName" or die "can't open $fileName for output";
+        open $fileRef, ">$fileName" or ( carp "can't open $fileName for output" and return undef );
     } else {
         #  we really want a tempfile, so put it in /tmp
@@ -621,9 +646,10 @@
     my $scheme = file_scheme($name); # The scheme, e.g., file://, path://
     if (defined $scheme and lc($scheme) eq 'neb') {
-        $self->_neb_start();
-        $status = $self->{nebulous}->delete( $name );
+        $self->_neb_start() or ( carp "Unable to start Nebulous" and return undef );
+        $status = eval { $self->{nebulous}->delete( $name ); };
+        ( carp "Unable to delete Nebulous handle $name" and return undef ) if $@;
     } else {
-        my $resolved = $self->file_resolve($name);
-        if ($resolved && -e $resolved) {
+        my $resolved = $self->file_resolve($name) or return undef;
+        if (defined $resolved and -e $resolved) {
             $status = unlink($resolved);
         }
@@ -638,9 +664,9 @@
     my $name = shift;
 
-    die "need name" unless $name;
+    ( carp "need redirection target" and return undef ) unless $name;
 
     my $filename = $self->file_resolve($name, 1);
 
-    die "cannot resolve $name" unless $filename;
+    ( carp "cannot resolve $name" and return undef ) unless $filename;
 
     if (! open(STDOUT, ">>$filename") ) {
@@ -651,5 +677,6 @@
         while (! open STDOUT, ">>$filename" ) {
             if ($try == $max_tries) {
-                die "failed to redirect stdout to $filename after trying $max_tries times";
+                carp "failed to redirect stdout to $filename after trying $max_tries times";
+                return undef;
             }
             sleep 5;
@@ -658,5 +685,7 @@
         print STDERR "   redirect stdout to $filename succeded on try $try\n";
     }
-    open STDERR, ">>$filename" or die "failed to redirect stderr to $filename";
+    open STDERR, ">>$filename" or ( carp "failed to redirect stderr to $filename" and return undef );
+
+    return 1;
 }
 
@@ -676,5 +705,5 @@
     my $name = shift;                # File name for which to prepare
     my $workdir = shift;        # Working directory
-    my $template = shift;        # Template filename from which to get working directory if 
+    my $template = shift;        # Template filename from which to get working directory if
 
     if (defined $workdir) {
@@ -692,8 +721,8 @@
     # not guaranteed to have a scheme (path:// or file://) - might be /PATH/foobar
     # a relative path (PATH/foobar) is invalid here
-    my $resolved = $self->convert_filename_absolute( $name );
+    my $resolved = $self->convert_filename_absolute( $name ) or return undef;
     my ( $vol, $dirs, $file ) = File::Spec->splitpath( $resolved );
     unless (-d $dirs) {
-        system("mkdir -p $dirs") == 0 or (carp "Can't create directory $dirs" and exit($PS_EXIT_DATA_ERROR));
+        system("mkdir -p $dirs") == 0 or ( carp "Can't create directory $dirs" and return undef );
     }
 
@@ -716,8 +745,8 @@
     # not guaranteed to have a scheme (path:// or file://) - might be /PATH/foobar
     # a relative path (PATH/foobar) is invalid here
-    my $resolved = $self->convert_filename_absolute( $outroot );
+    my $resolved = $self->convert_filename_absolute( $outroot ) or return undef;
     my ( $vol, $dirs, $file ) = File::Spec->splitpath( $resolved );
     unless (-d $dirs) {
-        system("mkdir -p $dirs") == 0 or (carp "Can't create directory $dirs" and exit($PS_EXIT_DATA_ERROR));
+        system("mkdir -p $dirs") == 0 or ( carp "Can't create directory $dirs" and return undef );
     }
 
@@ -734,5 +763,5 @@
     unless (defined $self and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -741,9 +770,9 @@
 
     ## if this is already an absolute path (/PATH/file), just return the path
-    unless (defined $scheme) { 
+    unless (defined $scheme) {
         if ($name =~ m|^/|) { return $name; }
         # without a leading slash, this is an error
         carp "Relative file name provided: relative paths are not permitted.";
-        exit($PS_EXIT_SYS_ERROR);
+        return undef;
     }
 
@@ -751,5 +780,5 @@
 
     if (lc($scheme) eq 'file') {
-        # the above strips of the leading slash; replace it for file:// 
+        # the above strips of the leading slash; replace it for file://
         $name = '/' . $name;
         return $name;
@@ -764,10 +793,6 @@
     }
 
-    # looks like we cannot reach here without an invalid scheme.  
-    # programming error?
-    # return $name;
-
-    carp "Programming error";
-    exit($PS_EXIT_PROG_ERROR);
+    # It's already absolute
+    return $name;
 }
 
@@ -777,10 +802,10 @@
     my $self = shift;                # Configuration object
     my $name = shift;                # raw name
-    
+
     unless (defined $self and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
-    }
-    
+        return undef;
+    }
+
     # First, check to see if it's already in a relative form
     my $scheme = file_scheme($name); # The scheme, e.g., file, path
@@ -790,5 +815,5 @@
             # We may as well search for a 'better' path
             # guaranteed to have a scheme (path:// or file://)
-            $name = $self->convert_filename_absolute( $name );
+            $name = $self->convert_filename_absolute( $name ) or return undef;
         } elsif ($scheme eq 'neb') {
             # No chance of changing anything --- move along
@@ -796,8 +821,8 @@
         }
     }
-    
+
     $name = File::Spec->canonpath( $name); # Clean up
     my @dirs = File::Spec->splitdir( $name );
-    
+
     my $path_list = metadataLookupMD($self->{_siteConfig}, 'DATAPATH'); # List of paths
     my $best_path;
@@ -809,5 +834,5 @@
       $path =~ s|/*$||;
       my @path_dirs = File::Spec->splitdir( $path );
-      
+
       # Check if the path is suitable
       next if scalar @path_dirs > scalar @dirs;
@@ -823,5 +848,5 @@
       }
   }
-    
+
     $name =~ s|^/||;
     $name =~ s|/$||;
@@ -845,5 +870,5 @@
     unless (defined $self and defined $name and defined $type) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -854,13 +879,13 @@
             return undef;
         }
-        
+
         # rejections are saved as a recipe: REJECTIONS
         my @rejContents = `ppConfigDump -dump-recipe REJECTIONS -camera $camera -`;
-        
+
         # load from resulting psMetadataConfig
         $self->{rejection} = $parser->parse( join '', @rejContents); # The rejection metadata
         unless (defined $self->{rejection}) {
             carp "Unable to parse REJECTION recipe for $camera.";
-            exit($PS_EXIT_CONFIG_ERROR);
+            return undef;
         }
     }
@@ -873,5 +898,5 @@
           unless ($item->{class} eq "metadata") {
               carp "$name within REJECTIONS is not of type METADATA";
-              exit($PS_EXIT_PROG_ERROR);
+              return undef;
           }
           my $limits = $item->{value}; # List of rejection limits
@@ -880,7 +905,5 @@
           foreach my $limit (@$limits) {
               if ($limit->{name} eq 'FILTER') {
-                  if ($limit->{value} eq '*' or
-                      (defined $filter and
-                       $limit->{value} eq $filter)) {
+                  if ($limit->{value} eq '*' or (defined $filter and $limit->{value} eq $filter)) {
                       last;
                   }
@@ -888,5 +911,5 @@
               }
           }
-          
+
           foreach my $limit (@$limits) {
               return $limit->{value} if $limit->{name} eq $name;
@@ -915,5 +938,5 @@
     unless (defined $self and defined $name and defined $output) {
         carp "Programming error: required inputs left undefined";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -929,5 +952,5 @@
             return undef;
         }
-        
+
         $filerules = metadataLookup($camera, 'FILERULES');        # File rules
         unless (defined $filerules) {
@@ -935,13 +958,15 @@
             return undef;
         }
-        
+
         if ($filerules->{class} eq "scalar" and $filerules->{type} eq "STR") {
             # Allow indirection to a file
             my $filename = $self->_find_config($filerules->{value}); # Resolved filename
+            ( carp "Unable to find file rules file" and return undef ) unless defined $filename;
+
             # Read the file
             my $file;                # File handle
             unless (open $file, $filename) {
                 carp "Unable to open filerules file $filename: $!";
-                exit($PS_EXIT_CONFIG_ERROR);
+                return undef;
             }
             my @contents = <$file>;
@@ -973,5 +998,5 @@
         unless (defined $component) {
             carp "Programming error";
-            exit($PS_EXIT_PROG_ERROR);
+            return undef;
         }
         $filename =~ s/\{CHIP\.NAME\}/$component/;
@@ -980,5 +1005,5 @@
 
     return $filename;
-}   
+}
 
 # Return an EXTNAME From the EXTNAME.RULE table in the camera configuration
@@ -991,5 +1016,5 @@
     unless (defined $self and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1015,5 +1040,5 @@
         unless (defined $component) {
             carp "Programming error";
-            exit($PS_EXIT_PROG_ERROR);
+            return undef;
         }
         $extname =~ s/\{CHIP\.NAME\}/$component/;
@@ -1021,5 +1046,5 @@
 
     return $extname;
-}   
+}
 
 # Return catdir for tessellation, from TESSELLATIONS within the site configuration
@@ -1031,5 +1056,5 @@
     unless (defined $self and defined $self->{_siteConfig} and defined $tess_id) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1037,5 +1062,5 @@
     unless (defined $tessellations) {
         carp "Can't find TESSELLATIONS in site configuration.\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1050,5 +1075,5 @@
     if (defined $scheme and lc($scheme) eq 'neb') {
         carp "Tessellation $tess_id refers to a Nebulous path: $catdir\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1065,5 +1090,5 @@
     unless (defined $self and defined $self->{_siteConfig} and defined $dvodb) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1071,5 +1096,5 @@
     unless (defined $catdirs) {
         carp "Can't find DVO.CATDIRS in site configuration.\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1084,5 +1109,5 @@
     if (defined $scheme and lc($scheme) eq 'neb') {
         carp "DVO catdir $dvodb refers to a Nebulous path: $catdir\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1098,5 +1123,5 @@
     unless (defined $self and defined $self->{_siteConfig} and defined $dvodb) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1104,5 +1129,5 @@
     unless (defined $catdirs) {
         carp "Can't find PSASTRO.CATDIRS in site configuration.\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1117,5 +1142,5 @@
     if (defined $scheme and lc($scheme) eq 'neb') {
         carp "PSASTRO catdir $dvodb refers to a Nebulous path: $catdir\n";
-        exit($PS_EXIT_CONFIG_ERROR);
+        return undef;
     }
 
@@ -1130,5 +1155,5 @@
     unless (defined $self) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1158,5 +1183,5 @@
     unless (defined $self and defined $reduction and defined $name) {
         carp "Programming error --- inputs undefined";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1180,13 +1205,14 @@
             return undef;
         }
-        
+
         if ($reductionClasses->{class} eq "scalar" and $reductionClasses->{type} eq "STR") {
             # Allow indirection to a file
             my $filename = $self->_find_config($reductionClasses->{value}); # Resolved filename
+            ( carp "Unable to find reduction classes file" and return undef ) unless defined $filename;
             # Read the file
             my $file;                # File handle
             unless (open $file, $filename) {
                 carp "Unable to open reductionClasses file $filename: $!";
-                exit($PS_EXIT_CONFIG_ERROR);
+                return undef;
             }
             my @contents = <$file>;
@@ -1203,10 +1229,8 @@
 
     my $class = metadataLookupMD($reductionClasses, $reduction) or # Class of interest
-        (carp "Can't find $reduction in REDUCTION in camera configuration.\n" and
-         exit($PS_EXIT_CONFIG_ERROR));
+        ( carp "Can't find $reduction in REDUCTION in camera configuration.\n" and return undef );
 
     my $actual = metadataLookupStr($class, $name) or # The actual recipe name of interest
-        (carp "Can't find $name in $class in REDUCTION in camera configuration.\n" and
-         exit($PS_EXIT_CONFIG_ERROR));
+        (carp "Can't find $name in $class in REDUCTION in camera configuration.\n" and return undef );
 
     return $actual;
@@ -1226,19 +1250,19 @@
     }
 
-    my $dvoImageExtract = can_run('dvoImageExtract') or die "Can't find dvoImageExtract";
-    
+    my $dvoImageExtract = can_run('dvoImageExtract') or ( carp "Can't find dvoImageExtract" and return undef );
+
     my $tess_dir = $self->tessellation_catdir( $tess_id ); # Tessellation catdir for DVO
     unless (defined $tess_dir) {
         carp "Can't get list of tessellations.";
-        return 0;
-    }
-    $tess_dir = $self->convert_filename_absolute( $tess_dir );
+        return undef;
+    }
+    $tess_dir = $self->convert_filename_absolute( $tess_dir ) or return undef;
 
     unless ($self->file_exists( $outname )) {
-        my $outnameResolved = $self->file_create( $outname ); # Resolved filename, for Nebulous
+        my $outnameResolved = $self->file_create( $outname ) or return undef; # Resolved filename, for Nebulous
         my $command = "$dvoImageExtract -D CATDIR $tess_dir $skycell_id -o $outnameResolved";
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
             run(command => $command, verbose => $verbose);
-        die "Unable to perform dvoImageExtract for $tess_id $skycell_id\n" unless ($success and $self->file_exists( $outname ));
+        ( carp "Unable to perform dvoImageExtract for $tess_id $skycell_id\n" and return undef ) unless ($success and $self->file_exists( $outname ));
     }
 
@@ -1258,5 +1282,5 @@
         unless (defined $value) {
             carp "Unable to find environment variable $name";
-            exit($PS_EXIT_SYS_ERROR);
+            return undef;
         }
         $dir =~ s/\$\{?$name\}?/$value\//;
@@ -1272,5 +1296,5 @@
     unless (defined $mdc and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
@@ -1285,5 +1309,5 @@
     return undef;
 }
-   
+
 
 # Lookup the metadata, checking the type is STR
@@ -1325,5 +1349,5 @@
     unless (defined $mdc and defined $name) {
         carp "Programming error";
-        exit($PS_EXIT_PROG_ERROR);
+        return undef;
     }
 
