CREATE OR REPLACE FUNCTION sfunc_exception_union(geom_a geometry, geom_b geometry)
    RETURNS geometry
    AS $$

    DECLARE

    err_txt1 text;
    -- err_txt2 text;
    -- err_txt3 text;

    pos_ex text;
    pos_ex_x numeric;
    pos_ex_y numeric;

    BEGIN   

    RETURN ST_Union(geom_a, geom_b);

    EXCEPTION
        WHEN OTHERS THEN
         GET STACKED DIAGNOSTICS
	 err_txt1 = MESSAGE_TEXT;
	 pos_ex = substring(err_txt1 from E'at [0-9]+\.[0-9]+ [0-9]+\.[0-9]+');
	 pos_ex_x = split_part(pos_ex, ' ', 2);
	 pos_ex_y = split_part(pos_ex, ' ', 3);
	 raise notice 'An error occured at this Position: % %', pos_ex_x, pos_ex_y;

	BEGIN
	raise notice 'Try Make valid ....';
	RETURN ST_Union(ST_MakeValid(geom_a), ST_MakeValid(geom_b));
		
	EXCEPTION
		WHEN OTHERS THEN
			BEGIN			
			raise notice 'Try Snapping 0.00001 ....';
			RETURN ST_Union(ST_snaptogrid(geom_a, 0.00001), ST_snaptogrid(geom_b, 0.00001));
			-- RETURN ST_Union(ST_Buffer(geom_a, 1), ST_Buffer(geom_b, 1));

			EXCEPTION
				WHEN OTHERS THEN

				BEGIN
				raise notice 'Try Snapping 0.0001 ....';
				RETURN ST_Union(ST_snaptogrid(geom_a, 0.0001), ST_snaptogrid(geom_b, 0.0001));

					EXCEPTION
					WHEN OTHERS THEN
					BEGIN
					raise notice 'Try Snapping 0.001 ....';
					RETURN ST_Union(ST_snaptogrid(geom_a, 0.001), ST_snaptogrid(geom_b, 0.001));

					EXCEPTION
						WHEN OTHERS THEN
						BEGIN
						raise notice 'Could not fix exception ....';
						-- RETURN ST_GeomFromText('POLYGON EMPTY'); -- Does not work because all so far aggregated rows will be lost
						RETURN geom_a; -- Must be something else?
						END;
					END;
				END;
			END;
		END;


-- Create temp table with point geometries of unfixed exceptions?
-- raise notice ''; raise notice ''; raise notice 'Position of unfixed exception in tmp_err';


END
$$ LANGUAGE 'plpgsql' STRICT;


-- Drop aggregate safe_union_line(geometry)
CREATE AGGREGATE safe_union_line(geometry)
(
    sfunc = sfunc_exception_union,
    stype = geometry
    ,initcond = 'LINESTRING EMPTY'
);

-- Drop aggregate safe_union_poly(geometry)
CREATE AGGREGATE safe_union_poly(geometry)
(
    sfunc = sfunc_exception_union,
    stype = geometry
    ,initcond = 'POLYGON EMPTY'
);
