diff --git a/parsers/survex.py b/parsers/survex.py
index fc234d0..8f3b65d 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -6,7 +6,7 @@ import copy
 import subprocess
 
 from pathlib import Path
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, date
 
 from django.utils.timezone import get_current_timezone
 from django.utils.timezone import make_aware
@@ -32,7 +32,7 @@ todo = '''Also walk the entire tree in the :loser: repo looking for unconnected
         wider troggle system (the name is not a hyperlink) - apparently randomly. 
         GetPersonExpeditionNameLookup() needs to be fixed.
         
-- fix THREEDCACHEDIR and put .3d files in same folder as .svx and fix CaveView
+-#BUG, if *date comes after *team, the person's date is not set at all. It needs re-setting at the endof the block.
 
 - LoadSurvexFile() Creates a new current survexfile and valid .survexdirectory
         The survexblock passed-in is not necessarily the parent. FIX THIS.
@@ -219,7 +219,7 @@ class LoadingSurvex():
                         teammembers.append((personexpedition, tm))
                         personrole = SurvexPersonRole(survexblock=survexblock, personexpedition=personexpedition, personname=tm)
                         personrole.save()
-                        personrole.expeditionday = survexblock.expeditionday
+                        personrole.expeditionday = survexblock.expeditionday #BUG, if *date comes after *team, this is NOT SET.
                         if personexpedition:
                             personrole.person=personexpedition.person
                             self.currentpersonexped.append(personexpedition)
@@ -681,10 +681,14 @@ class LoadingSurvex():
                 #print("\n"+message)
                 #print("\n"+message,file=sys.stderr)
                 return
-        message = f" ! {headpath} is not a fully-registered cave. (while creating '{includelabel}' sfile & sdirectory in survex parsing)"
+        message = f" ! Error: '{headpath}' not a cave or in the ignore list of surface surveys. (while creating '{includelabel}')"
         print("\n"+message)
         print("\n"+message,file=sys.stderr)
         DataIssue.objects.create(parser='survex', message=message)
+        print(f' # datastack in  LoadSurvexFile:{includelabel} type:', end="",file=sys.stderr)
+        for dict in self.datastack:
+            print(f'{dict["type"].upper()}   ', end="",file=sys.stderr)
+        
 
     def LoadSurvexFile(self, svxid):
         """Creates SurvexFile in the database, and SurvexDirectory if needed
@@ -722,9 +726,9 @@ class LoadingSurvex():
             newdirectory.cave = cave
             newfile.cave   = cave
             #print("\n"+str(newdirectory.cave),file=sys.stderr)
-        else:
+        else: # probably a surface survey
             self.ReportNonCaveIncludes(headpath, svxid)
-
+            
         if not newfile.survexdirectory:
             message = " ! SurvexDirectory NOT SET in new SurvexFile {} ".format(svxid)
             print(message)
@@ -1200,36 +1204,47 @@ class LoadingSurvex():
         svx_t = now - 365*24*3600
 
         def runcavern():
-            '''This assumes all survex files have unique names and they are taken from many folders but the output is all put 
-            into the same folder. A serious potential bug. Import parser checks uniqueness but much better not to do it like this.
-            # see design docum in troggle/templates/cave.html
-            # and views/caves.py rendercave()
+            '''regenerates the .3d file from the .svx if it is older than the svx file, or older than the software,
+            or randomly using chaosmonkey() just to keep things ticking over.
             '''
             print(f" -  Regenerating stale (or chaos-monkeyed) cavern .log and .3d for '{fullpath}'\n     at '{logpath}'\n")
             print(f"days svx old: {(svx_t - log_t)/(24*3600):.1f}  cav:{(cav_t - log_t)/(24*3600):.1f}   log old: { (now - log_t)/(24*3600):.1f}")
             
             outputdir = Path(str(f'{fullpath}.svx')).parent
-            sp = subprocess.run([settings.CAVERN, "--log", f'--output={outputdir}', f'{fullpath}.svx'])
+            sp = subprocess.run([settings.CAVERN, "--log", f'--output={outputdir}', f'{fullpath}.svx'],
+                                    capture_output=True, check=False, text=True)
             if sp.returncode != 0:
-                print(f'fullpath: {fullpath}:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
+                message = f' ! Error running {settings.CAVERN}: {fullpath}' 
+                DataIssue.objects.create(parser='entrances', message=message)
+                print(message)
+                print(f'stderr:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
             self.caverncount += 1
             
             # should also collect all the .err files too and create a DataIssue for each one which 
             # - is nonzero in size
             # - has Error greater than 5% anywhere, or some other more serious error
 
-        svxpath = fullpath + ".svx"
-        logpath = fullpath + ".log"
+        svxpath = Path(fullpath + ".svx")
+        logpath = Path(fullpath + ".log")
         outputdir = Path(svxpath).parent
 
-        if not os.path.isfile(logpath):
+        if not logpath.is_file(): # always run if logfile not there
             runcavern()
             return
 
+        self.caverndate = now - 2*365*24*3600
+
         if not self.caverndate:
-            completed_process = subprocess.run(["which", "{}".format(settings.CAVERN)], 
-                                    capture_output=True, check=True, text=True)
-            self.caverndate = os.path.getmtime(completed_process.stdout.strip())
+            sp = subprocess.run(["which", "{}".format(settings.CAVERN)], 
+                                    capture_output=True, check=False, text=True)
+            if sp.returncode != 0:
+                message = f' ! Error running "which" on {settings.CAVERN}' 
+                DataIssue.objects.create(parser='entrances', message=message)
+                print(message)
+                print(f'stderr:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
+                self.caverndate = os.path.getmtime(sp.stdout.strip())
+            else:
+                self.caverndate = now - 2*365*24*3600
         cav_t = self.caverndate
         log_t = os.path.getmtime(logpath)
         svx_t = os.path.getmtime(svxpath)
@@ -1244,7 +1259,7 @@ class LoadingSurvex():
         if cav_t - log_t > 0:          # new version of cavern
             runcavern()
             return
-        if chaosmonkey(400):           # one in every 400 runs
+        if chaosmonkey(350):           # one in every 350 runs
             runcavern()
 
 def FindAndLoadSurvex(survexblockroot):
@@ -1332,6 +1347,7 @@ def FindAndLoadSurvex(survexblockroot):
             svxlines = fcollate.read().splitlines()
     #pr2 = cProfile.Profile()
     #pr2.enable()
+    print("    ", file=sys.stderr,end='')
     #----------------------------------------------------------------
     svx_load.LinearLoad(survexblockroot,survexfileroot.path, svxlines)
     #----------------------------------------------------------------
@@ -1385,6 +1401,7 @@ def LoadSurvexBlocks():
     DataIssue.objects.filter(parser='survex').delete()
     DataIssue.objects.filter(parser='survexleg').delete()
     DataIssue.objects.filter(parser='survexunits').delete()
+    DataIssue.objects.filter(parser='entrances').delete()
 
     survexfileroot = MakeSurvexFileRoot()
     # this next makes a block_object assciated with a file_object.path = SURVEX_TOPNAME
@@ -1421,21 +1438,48 @@ def LoadPositions():
 
         # print(" -  Regenerating stale cavern .log and .3d for '{}'\n    days old: {:.1f}    {:.1f}    {:.1f}".
         #    format(topdata, (svx_t - d3d_t)/(24*3600), (cav_t - d3d_t)/(24*3600), (now - d3d_t)/(24*3600)))
-        # subprocess.call([settings.CAVERN, "--log", f"--output={topdata}", f"{topdata}.svx"])
+
+        file3d = Path(f'{topdata}.3d')
         try:
             sp = subprocess.run([settings.CAVERN, "--log", f"--output={outputdir}", f"{topdata}.svx"], 
-                                    capture_output=True, check=True, text=True)
+                                    capture_output=True, check=False, text=True) #check=False means exception not raised
             if sp.returncode != 0:
-                print(f'topdata: {topdata}:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
-
-            # print(" -  Regenerating {} {}.3d  in  {}".format(settings.SURVEXPORT, topdata, settings.SURVEX_DATA))
-            sp = subprocess.run([settings.SURVEXPORT, '--pos', f'{topdata}.3d'], cwd = settings.SURVEX_DATA, 
-                                    capture_output=True, check=True, text=True)
-            if sp.returncode != 0:
-                print(f'topdata: {topdata}:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
-        except:
-            print(f'topdata: {topdata}:\n\n' + str(sp.stderr) + '\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
+                message = f' ! Error: cavern: creating {file3d} in runcavern3()'
+                DataIssue.objects.create(parser='survex', message=message)
+                print(message)
+                
+                # find the errors in the 1623.log file
+                sp = subprocess.run(["grep", "error:", f"{topdata}.log"], 
+                                        capture_output=True, check=False, text=True) #check=False means exception not raised
+                message = f' ! Error: cavern: {sp.stdout}'
+                DataIssue.objects.create(parser='survex', message=message)
+                print(message)
 
+        except: 
+            message = " ! CalledProcessError 'cavern' in runcavern3() at {topdata}."
+            DataIssue.objects.create(parser='survex', message=message)
+            print(message)
+            
+            if file3d.is_file():
+                message = " ! CalledProcessError. File permissions {file3d.stat().st_mode} on {str(file3d)}"
+                DataIssue.objects.create(parser='survex', message=message)
+                print(message)
+                
+        if file3d.is_file(): # might be an old one though
+            try:
+                # print(" -  Regenerating {} {}.3d  in  {}".format(settings.SURVEXPORT, topdata, settings.SURVEX_DATA))
+                sp = subprocess.run([settings.SURVEXPORT, '--pos', f'{file3d}'], cwd = settings.SURVEX_DATA, 
+                                        capture_output=True, check=False, text=True)
+                if sp.returncode != 0:
+                    print(f' ! Error: survexport creating {topdata}.pos in runcavern3().\n\n' + str(sp.stdout)  + '\n\nreturn code: ' + str(sp.returncode))
+            except: 
+                message = " ! CalledProcessError 'survexport' in runcavern3() at {file3d}." 
+                DataIssue.objects.create(parser='entrances', message=message)
+                print(message)
+        else:
+            message = f" ! Failed to find {file3d} so aborting generation of new .pos, using old one if present"
+            DataIssue.objects.create(parser='entrances', message=message)
+            print(message)
 
     topdata = os.fspath(Path(settings.SURVEX_DATA) / settings.SURVEX_TOPNAME)
     print(' - Generating a list of Pos from %s.svx and then loading...' % (topdata))
@@ -1476,7 +1520,13 @@ def LoadPositions():
         svxid, number,  point_type, label = pt
         mappoints[svxid]=True
 
-    posfile = open("%s.pos" % (topdata))
+    if not Path(pospath).is_file():
+        message = f" ! Failed to find {pospath} so aborting generation of entrance locations. "
+        DataIssue.objects.create(parser='entrances', message=message)
+        print(message)
+        return
+
+    posfile = open(pospath)
     posfile.readline() #Drop header
     try:
         survexblockroot = SurvexBlock.objects.get(name=ROOTBLOCK)