If the geometry optimization is failing to converge fairly often, it is probably better to not try to run the calculations automatically in sequence and to instead check on the geometry before starting the excited state calculation.
Having said that, there is a way to define a sequence of Gaussian jobs that I think could fit your use case. In a Gaussian input file, you can write multi jobs, separated by a --Link1--
header. These jobs can use information from previous steps through the check point file. So in your case, you could do something like (adding in your specific keywords and actual geometry).
%chk=initial_geom.chk
#p opt
Initial Geom Opt
0 1
H 0.0 0.0 0.0
H 0.0 0.0 1.0
--Link1--
%oldchk=initial_geom.chk
%chk=better_geom.chk
#p opt guess=read geom=check !additional keywords to improve convergence
!Should finish almost immediately if already converged
Better Geometry
0 1
--Link1--
%oldchk=better_geom.chk
%chk=excited.chk
#p guess=read geom=check !Excited state keywords
Excited calc
0 1
This should do the initial geometry optimization, then start another optimization with your keywords to ensure convergence (which should end very quickly if the calculation is already converged), and finally run an excited state calculation on this improved geometry.
If you weren't actually sure that the 2nd step would converge, you could add an arbitrary number of intermediate steps in an effort to get a converged geometry. If you really wanted something that keeps trying the optimization until it is converged, I believe you would need an external shell/python/etc script to manage the Gaussian calculations, parse their output, and determine the need for additional calculations.
However, as I mentioned, I think anything beyond the three step approach I described here would be a worse idea than just submitting all the geometry optimizations separately, manually addressing any issues for failed cases, and then submitting the excited state calculations.