New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for possible exception when fetching work item information #1395
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I am sympathetic to your cause and only have some small change requests.
Please also add an entry ala
An error in fetching the workitems associated to a changeset no longer aborts the fetch/clone (#1395 @drolevar)
to the release notes here:
https://github.com/git-tfs/git-tfs/blob/master/doc/release-notes/NEXT.md
Url = Linking.GetArtifactUrl(wi.Uri.AbsoluteUri) | ||
}); | ||
} | ||
catch (TeamFoundationServerException e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am currious, do you remember which property caused the exception? At least the code in HasWorkItems method suggests that the WorkItems array can be fetched.
Please check for the concrete error TF201077, to ensure we are not accidentially ignoring other errors.
See e.g. the code in HasWorkItems
a few lines below, how to check the exception message method, inlined here
protected virtual bool HasWorkItems(Changeset changeset)
{
// This method wraps changeset.WorkItems, because
// changeset.WorkItems might result to ConnectionException: TF26175: Team Foundation Core Services attribute 'AttachmentServerUrl' not found.
// in this case assume that it is initialized to null
// NB: in VS2011 a new property appeared (AssociatedWorkItems), which works correctly
WorkItem[] result = null;
try
{
result = Retry.Do(() => changeset.WorkItems);
}
catch (ConnectionException exception)
{
if (!exception.Message.StartsWith("TF26175:"))
throw;
}
return result != null && result.Length > 0;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I've refactored the code a bit using both AssociatedWorkItems (which works even for malformed work items) and WorkItems to update the TfsWorkItem instances (which can cause an exception).
cca14a8
to
d7e88bb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the commens inline
// in this case assume that it is initialized to null | ||
// NB: in VS2011 a new property appeared (AssociatedWorkItems), which works correctly | ||
WorkItem[] result = null; | ||
var workItems = changeset.AssociatedWorkItems.Select(wi => new TfsWorkitem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a comment in this method explaining why we are first using the AssociatedWorkItems
and then
the WorkItems
?
I already have spent several minutes on the Join
below to understand that it will only return the WorkItems which are in both sets (the intersection). I fear that in half a year, I would be completely lost when looking at the code again.
if (!exception.Message.StartsWith("TF26175:")) | ||
throw; | ||
Trace.TraceWarning(e.Message); | ||
return workItems; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we return the only half filled TfsWorkitem
s in case we have an error.
Furthermore, if e.g. AssociatedWorkItems.Lenght == 3 and we fail on the first work item when joining,
then all the subsequent work items will be silently ignored. I believe your first version didn't have this problem.
On the other hand you mentioned that due the prefiltering on the AssociatedWorkItems the error no longer exists.
Perhaps this is an artificial problem only?
Can you double check if this is true? If so, we So if there are e.g.
|
||
return result != null && result.Length > 0; | ||
protected virtual bool HasWorkItems(Changeset changeset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method not longer needs to be overriden in any of its users, so either make it
protected virtual bool HasWorkItems(Changeset changeset) | |
private bool HasWorkItems(Changeset changeset) |
or better remove it altoegether and call GetWorkItems unconditonally and let it return an Enumerable.Empty<ITfsWorkitem>()
if there are none.
Edited to fix a formating error On another note and while you are looking in this area, I was wondering if we can get rid of the access to We would need to get rid of these two fields public interface ITfsWorkitem
{
int Id { get; set; }
string Title { get; set; }
- string Description { get; set; }
- string Url { get; set; }
} as they have no representation in the
@drolevar Are the URLs of the WorkItems usable on your end? My current working theory is that this URL schema was working in the past, e.g. with an older TFS server the URL Adding @pmiossec to the loop, as he introduced the |
@siprbaum I agree with your suggestion of using AssociatedWorkItems instead of WorkItems. |
I have added this url because at the time TFS server was displaying something or redirecting it. |
I created #1396 to fix the wrong URLs and also prepare for switching to Any change you (@drolevar or @pmiossec) could have a look at it? If we can agree that this is the way forward, we can merge ot #1396 first and then rebase the current PR on top of that, which would make the code simpler. |
@drolevar I'll merged the preperations in the meantime, so the code can be rebased. I did only get rid of the |
d7e88bb
to
a9cb007
Compare
@siprbaum OK, updated the PR. Honestly, it was more removing than adding. Verified that it works both for changesets with and without associated work items. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the changes and they are reasonable.
One last thing, can you please --amend
the commit message to describe what the original problem was and how the fix prevents this error to happen? I prefere to have this in the commit message so that when I later need to look at the code histroy I have the explanation right there.
It is much easier to deal with it that way than to go hunting in the github PR for it.
Otherwise, I think this can go in.
In certain cases of legacy TFS projects using Changeset::WorkItems could cause a WorkItemTypeDeniedOrNotExistException (error TF201077) and cloning process stopped. This change uses AssociatedWorkItems instead which works fine even in this case.
a9cb007
to
f710a91
Compare
@drolevar Thanks for your work, I didn't notice that you already changed the message, otherwise I would have merged it earlier. |
When trying to convert a legacy repo, I was getting the following exception, probably because some internal discrepancies in the project definition:
TF201077: The work item type cannot be found. It may have been renamed or destroyed.
I've added this try/catch to enable the process to continue even if some work item information cannot be fetched.