R crashes due to an error in vertex.attr.comb and edge.attr.comb functions


The program below is an attempt to create a “quotient graph”. The equivalence relation is being strongly connected. When we purposely create an error in the name parameter of the vertex.attr.comb function (set x to xx) then R gives an error and after a few seconds crashes.

When we make a similar error in the name parameter of the edge.attr.comb function (set x to xx) then R exhibits the same behaviour.
Both contract and simplify are straightforward wrappers into C. So my question is: is this an R-interface or a C igraph library problem?

# https://github.com/igraph/rigraph/issues/398
# create quotient graph, g/~, where ~ equivalence relation "strongly connected"
g <- graph_from_literal( 1-+2, 2-+3, 3-+1, 1-+4, 2-+4, 2-+5, 3-+5, 3-+6, 1-+6)

edge_attr(g) <- list(name = letters[seq_len(ecount(g))]
                    , weight = rep(1, ecount(g) )
# g <- delete_vertex_attr(g, name="name")                                                              # no crash, when commented out 
SCC <- clusters(g, mode=c("strong"))
vg <- contract(g
              , SCC$membership
              , vertex.attr.comb=list( category="first"
                                     , name=function(x) paste(x[seq_len(length(x))], collapse="=")
              )                                                                                        # crash when name=function(z)
dev.new(); plot(vg, edge.label = paste(E(vg)$name, E(vg)$weight, sep=","))

qg <- simplify( vg
              , remove.loops=FALSE
              , edge.attr.comb=list( category="first"
                                   , name=function(x) paste(x[seq_len(length(x))], collapse="/")
                                   , weight="sum"

dev.new(); plot(qg, edge.label = E(qg)$weight)

I strongly suspect that this is an issue with the R interface and a bug should be filed in the rigraph repository. Basically, what happens is that R delegates the outer simplify() call to igraph’s C layer; igraph does its job and then eventually calls the R function that combines the edge attributes. This function invocation throws an error, but the glue code between C-igraph and R-igraph (which resides in the rigraph repository) does not check whether R threw an error or not and proceeds as if everything went fine. From then on, the behaviour is undefined.

I’m thinking that it affects the R interface only because the Python interface handles a similar error correctly:

>>> g = Graph.GRG(100, 0.2)
>>> g.es["name"] = [100] * g.ecount()
>>> g.simplify(combine_edges = {"name": lambda x: no_such_variable})
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 1, in <lambda>
NameError: name 'no_such_variable' is not defined

I have (15-jul) created issue #398 here, but not received any comments until now. I assume this is the right place (?)