Construct exception tree from trace.

def _build_ex_tree(self):
        """Construct exception tree from trace."""
        # Load exception data into tree structure
        sep = self._exh_obj.callables_separator
        data = self._exh_obj.exceptions_db
        if not data:
            raise RuntimeError("Exceptions database is empty")
        # Add root node to exceptions, needed when tracing done
        # through test runner which is excluded from callable path
        for item in data:
            item["name"] = "root{sep}{name}".format(sep=sep, name=item["name"])
        self._tobj = ptrie.Trie(sep)
        try:
            self._tobj.add_nodes(data)
        except ValueError as eobj:
            if str(eobj).startswith("Illegal node name"):
                raise RuntimeError("Exceptions do not have a common callable")
            raise
        # Find closest root node to first multi-leaf branching or first
        # callable with exceptions and make that the root node
        node = self._tobj.root_name
        while (len(self._tobj.get_children(node)) == 1) and (
            not self._tobj.get_data(node)
        ):
            node = self._tobj.get_children(node)[0]
        if not self._tobj.is_root(node):  # pragma: no branch
            self._tobj.make_root(node)
            nsep = self._tobj.node_separator
            prefix = nsep.join(node.split(self._tobj.node_separator)[:-1])
            self._tobj.delete_prefix(prefix)
        self._print_ex_tree()