-
Notifications
You must be signed in to change notification settings - Fork 899
Cleanup error marshaling and generating code #183
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
Conversation
|
||
namespace LibGit2Sharp.Core | ||
{ | ||
internal class GitErrorMarshaler : ICustomMarshaler |
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.
Classy!
As discussed in #137, there are no so many error codes, and depending on the method being executed, the same error code may mean something different. I'm not in favor of exposing those My feeling is that if we're not able to infer correct exceptions from the (codes|categories|executionContext) there's zero chance that the consumer will be able to correctly handle those (codes|categories|executionContext) tuples by himself. Moreover, by exposing our own exceptions, I think we might be more committed to maintain their "contract" (what they mean, when they're thrown) rather than if we just hand out to the consumer what libgit2 just returned. However, there may be headaches down the road... For instance, when the Klass/Category is Thoughts? |
👍 for |
Even if we do add specific exception types for the variety of class/code combinations, I personally would still like access to the real libgit2 error codes in the actual exception objects. When dealing with exceptional behavior, I've always found that the more you can pull away the abstractions and get to the real information, the better. If we do go through and add new exception types that derive from |
Fair enough :) Please add them to the Exception.Data dictionary. |
Great idea. |
https://github.com/nulltoken/libgit2sharp/tree/err fails on Mono. Build log is available here |
https://github.com/tclem/libgit2sharp/tree/err should fix it. I don't have a mono setup to verify with right now unfortunately. |
Unfortunately, it doesn't. See the build log. I don't know if the same instance of Marshaler is used to call |
{ | ||
Data["libgit2.code"] = this.code = code; | ||
Data["libgit2.class"] = this.category = category; | ||
isLibraryError = true; |
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.
Why did you stop exposing the GitErrorCode
as a strongly typed property? We actually reference that in GHfW. Am I supposed to reach into Data["libgit2.code"]
instead? That makes the code uglier and feels more fragile.
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.
Why did you stop exposing the GitErrorCode as a strongly typed property?
I'm not sure to follow you. GitErrorCode
has been turned Internal
more than a year ago (cf 2bd0630)
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.
Ah, I think in our branch we exposed it as a property. Why would you make this internal and not give me anything else I can use to know exactly what the error is? Parsing exception messages is piss poor and likely to change. Reaching into the Data property is ugly too.
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.
The advantage of Data
is that it's automatically serialized, whereas custom properties are not. What about public properties that encapsulate retrieving the code/class from Data
?
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.
@dahlbyk Sure. As a consumer of the API, I sort of don't care what the backing storage of the properties are. As it stands, I have my own extension methods that do this, but it seems like a no-brainer to have it in the class as part of the API.
Another option is to implement the serialization constructors for the exception type per FX Design Guidelines: http://msdn.microsoft.com/en-us/library/ms229064.aspx
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.
Implementing deserialization isn't hard, it's just more effort than using Data
.
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.
Sure, I really don't care how it's done. :)
But while we're on the topic, it does seem odd to me because Data
is read/write, no? So that would allow any code along the stack to modify properties in there. Thus if you created GitErrorCode
as a wrapper property, it wouldn't really be readonly, though semantically that's exactly what I'd expect.
All for a little less effort?
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.
All for a little less effort?
It's not about avoiding implementing the deserialization. Although that's a nice side benefit :)
You can peek at the following comments for a better context
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.
@nulltoken ah, thanks for the context! I like the idea of exposing specific exception classes. But I didn't see such classes yet.
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.
Conflicts: LibGit2Sharp/LibGit2SharpException.cs
/// <param name = "context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param> | ||
protected LibGit2SharpException(SerializationInfo info, StreamingContext context) | ||
: base(info, context) | ||
public GitErrorCode Code |
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.
@tclem @haacked As previously discussed, I'm really not willing to make the GitErrorCode
and GitErrorCategory
types publicly exposed, nor to expose such properties. Indeed, I don't feel the grain is fine enough (yet?) to safely build a stable/long lasting error handling strategy.
Therefore, for now, I'd prefer to only expose int
typed values in the Data
dictionary.
This makes the libgit2 native error codes available for logging purpose.
In order to reduce the pain, we'll indeed have to add proper exceptions to LibGit2Sharp. Which one would you see fit?
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.
@tclem I manually merged it in vNext. I focused on making the native error data accessible but dropped the Marshaler for now.
Now that @travisbot is watching our back with a Mono build for each PR, it should be easier ;-) ❤️ |
This is my second attempt to clean up error handling a bit. Here are the highlights.
Class
orType
so I'm calling the libgit2 error classCategory
instead.GitError
, but we still have to manually do the UTF8 marshaling for the error messageCode
andCategory
are now available on the exception as true properties so that consumers can use them instead of parsing the error message we generate.This PR replaces #163