Replies: 8 comments 15 replies
-
I think this is a good idea and we can potentially create a |
Beta Was this translation helpful? Give feedback.
-
We should make sure to agree on API. My biggest concern with example, is that a I do have one idea, this is less extreme than a full public readonly struct TryGetValueResult<T>(T? Result, string ErrorMessage) // or exception, IDK.
{
public bool HasValue => this.Result != null; //Need to verify this is OK with new ctor syntax lol
} I am not great at names but something like this would at least keep a bool (and thus, likely 4/8 bytes due to padding) off the potential copy or alloc. -IF- we need to have nullable structs where a 'success' could still be null, we'd need a public static class TryOption
{
public static readonly NoValueSentinel = new Exception("No Value");
public static readonly NoValue<T>() => TryOption<T>.NoValue;
public static readonly Of<T>(T value) => new TryOption<T>(T value, null);
public static readonly Error<T>(Exception error) => new TryOption<T>(default, error);
}
public readonly struct TryOption<T>
{
//All the fun stuff to make this semi-serializable is elided here...
public static readonly NoValue = new TryOption<T>(default, TryOption.NoValueSentinel);
public readonly T? Value;
public readonly Exception? Error;
public TryOption(T? value, Exception? error)
{
Value = value;
Error = error;
}
public bool HasValue => Object.RefrenceEquals(Error, TryOption.NoValueSentinel);
public bool HasError => Error != null && !HasValue;
} |
Beta Was this translation helpful? Give feedback.
-
Although I agree that exceptions are expensive (not just in .Net but in general due to stack trace pinning and whatnot) and we shouldn't be using it to control application flow and instead only use it for, well, real exceptions, I have some comments that may help to drive the API shape:
That being said, in current C#/.Net, I would rather avoid using Yes, I understand that breaking changes are not fun, but I would suggest to do it once to whatever pattern we decide and stick with it. PS: Also, we should drop the Just my 2c. |
Beta Was this translation helpful? Give feedback.
-
Hi, agreed this is needed, suggested this in #441 but not had the time to pursue in earnest. I like the idea of @to11mtm's with the TryOption , and whilst I'll be happy to change my code, I think now it's released we should keep the current API calls as they are without breaking. Maybe change the name though?!! Rather, we could add a whole Try...... command suite on top. My suggestion if possible would be to take all the current calls and migrate them to not throw any exceptions at all but to return the TryOption in all cases with the exception as one of the fields. Personally I'd rather see a Success field too. We then take all the current API names and call the Try...... ones underneath, and bubble the exceptions That way we can have the new try calls at a lower level with the real code inside, and just the old API names on top for compatibility. E.g. Current
To something like
|
Beta Was this translation helpful? Give feedback.
-
(not directly related but I think we should review consumer next/fetch/consume methods exception driven recovery mechanisms as well) |
Beta Was this translation helpful? Give feedback.
-
(post edits: added |
Beta Was this translation helpful? Give feedback.
-
How about this as the option/result struct? |
Beta Was this translation helpful? Give feedback.
-
Have we reached a consensus? |
Beta Was this translation helpful? Give feedback.
-
As we all know Exceptions in .NET are costly, and unfortunately the SDK makes use of Exceptions pretty heavily. This can be exacerbated in certain situations especially.
For example, trying to GET a KV Record that does not exist:
GetEntryAsync
Will throw a
NatsKVKeyNotFoundException
.One proposed solution, that would not require breaking changes, is to add Try methods that will not throw exceptions, or will only throw exceptions in certain situations.
Example:
Beta Was this translation helpful? Give feedback.
All reactions