Thinking about this again, you're right, and we should check to see if all pools were destroyed before initiating destruction of the group.

I'm thinking of something along the lines of:

```erlang
-spec rm_group(atom()) -> ok | {error, {failed_delete_pools, [ #pool{} ]}}
rm_group(GroupName) ->
    case pg2:get_local_members(GroupName) of
        {error, {no_such_group, GroupName}} ->
            ok;
        Pools ->
            case rm_group_members(Pools) of
                [] ->
                    pg2:delete(GroupName);
                Failures ->
                    {error, {failed_rm_pools, Failures}}
            end
    end.

-spec rm_group_members([ pid() ]) -> [ #pool{} ].
rm_group_members(MemberPids) ->
    lists:foldl(
      fun(MemberPid, Acc) ->
              Pool = gen_server:call(MemberPid, dump_pool),
              case pooler_sup:rm_pool(Pool#pool.name) of
                  ok -> Acc;
                  _  -> [Pool | Acc]
              end
      end,
      [],
      MemberPids).
```

In the above code, calling `rm_group/1` multiple times will not destroy the pool group until all member pools are destroyed, and will return the information about the problematic member if destruction fails.

The `gen_server:call/2` function could potentially cause an exit exception, but I think that's something that we shouldn't need to deal with.

Are there any issues that you see?