Assigning to Run.Text causes NullRef

I’ve been debugging something for a long time. Deep in our code which applies 1000’s of regexp to documents, when we assign to a Run.Text we get a NullRef.

The Watch windows shows three lines:

  1. afterRun.Text is valid
  2. afterRun.Text is a string
  3. assigning to afterRun.Text fails

Is there something about a Run that could be invalid which would cause this?

Thanks, totally stuck here.

@ResearchSquare Could you please provide your input document and simple code that will allow us to reproduce the problem on our side? We will check the issue and provide you more information.

That might be very hard to do. My guess is that’s something about the full application, since it seems very unlikely performing a simple regexp will cause the problem. But it’s something I’ll have to experiment with if we cannot figure it out ourselves.

We run 1000’s of regexps against a single document. I’ll see if I can figure out if it’s 1 regexp that causes the problem or if it requires running all of them. It does happen only with certain documents.

This is with 24.2.0 but it was happening back with 21.10.0 which we were using also.

@ResearchSquare Thank you for additional information. But unfortunately, it is hard to say what might cause the problem without an ability to reproduce it on our side. I looked through the source code and do not see any possible causes of this problem. Generally it simply assigns the value to internal string variable, unless revision are not tracked in the document. In the later case additional action are performed with Run.

We figured this out. It was actually a System.ArgumentException that happened first, and this led to a bunch of System.NullReferenceExceptions. We were doing something like:

run.ParentParagraph.InsertBefore(formattedRun, run);

And it was failing with ArgumentException because if we were inside a “content control” the parent of the run was a StructuredDocumentTag rather than the Paragraph. I’m not sure why the ArgumentException led to the NullRefs. My guess is something we were doing was not “exception safe” so things got messed up if that exception file.

So I don’t think anything was Aspose’s fault here. Although content controls are super rare so it’s tricky to have to deal with a totally different hierarchy only in that rare case. I could imagine an API that hid that a bit more. But I have no specific suggestions.

@ResearchSquare Have you tried using ParentNode instead of ParentParagraph in your code? Please try modifying the following code:

run.ParentParagraph.InsertBefore(formattedRun, run);

to this:

run.ParentNode.InsertBefore(formattedRun, run);

It looks like in your case the Run is not direct child of the ParentParagraph because it is inside inline SDT. So InsertBefore throws an exception because reference node is not child of composite node where the new node is to be inserted.

Great that does seem to fix the ArgumentException!

That leads to a follow-up question. Are there any other situations where a run’s ParentNode isn’t its ParentParagraph? Like unrelated to content controls. I was thinking table cells but I tried that, didn’t seem to case.

If there were some other case, is this also the right fix in general? That is, is inserting into the run’s ParentNode just the right way to do it always?

That is can we safely use run.ParentNode.InsertBefore in all cases?

Thanks.

@ResearchSquare

There are not other such cases which comes to mind. But, the internal implementation of Inline.ParentParagraph property is the following:

/// <summary>
/// Retrieves the parent <see cref="Paragraph"/> of this node.
/// </summary>
public Paragraph ParentParagraph
{
    get { return (Paragraph)GetAncestor(NodeType.Paragraph); }
}

So theoretically there might be such case in future, if some other inline nodes container will be added into the model.

Yes, it is absolutely safe to use this code in all cases. The code inserts the new not into the same parent as the reference node. Node.ParentNode returns the immediate parent of this the node.

Okay great thanks for the guidance. Sounds good.

1 Like