Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. How about new syntactical sugar for exception checking?

How about new syntactical sugar for exception checking?

Scheduled Pinned Locked Moved The Lounge
htmlcomjsonquestion
42 Posts 27 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Chris Maunder

    We get a shiny new "?" operator that takes

    string result = null;
    if (field != null)
    {
    result = field.Value;
    }

    and converts this to

    string result = field?.Value

    So what about the case where we're handling a flaky API

    string result = null;
    try
    {
    result = DodgyApi.GetValue(); // may throw an exception
    }
    catch
    {
    result = null;
    }

    What would you suggest we do for that? What about a headasplode (*) operator

    string result = DodgyApi.GetValue*();

    where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

    cheers Chris Maunder

    R Offline
    R Offline
    Roger Wright
    wrote on last edited by
    #25

    No programming questions in the Lounge! ;P

    Chris Maunder wrote:

    Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

    Surely you jest! It's only 117° today, but we're supposed to warm up for the weekend.

    Will Rogers never met me.

    1 Reply Last reply
    0
    • C Chris Maunder

      We get a shiny new "?" operator that takes

      string result = null;
      if (field != null)
      {
      result = field.Value;
      }

      and converts this to

      string result = field?.Value

      So what about the case where we're handling a flaky API

      string result = null;
      try
      {
      result = DodgyApi.GetValue(); // may throw an exception
      }
      catch
      {
      result = null;
      }

      What would you suggest we do for that? What about a headasplode (*) operator

      string result = DodgyApi.GetValue*();

      where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

      cheers Chris Maunder

      D Offline
      D Offline
      Duncan Edwards Jones
      wrote on last edited by
      #26

      how about setting that as default for the whole app... you could use a constant like #ON_ERROR_RESUME_NEXT = true; ;P

      1 Reply Last reply
      0
      • N Nish Nishant

        You could always write a helper method.

        string GetString(int x)
        {
        throw new NotImplementedException();
        }

        void Foo()
        {
        string s = NoEx.Run(() => GetString(100));
        Console.WriteLine(s == null);
        }

        class NoEx
        {
        public static T Run<T>(Func<T> method)
        {
        try
        {
        return method();
        }
        catch
        {
        return default(T);
        }
        }
        }

        Not as clean as syntactic sugar, but fairly close :-)

        Regards, Nish


        Website: www.voidnish.com Blog: voidnish.wordpress.com

        CPalliniC Offline
        CPalliniC Offline
        CPallini
        wrote on last edited by
        #27

        :thumbsup:

        In testa che avete, signor di Ceprano?

        1 Reply Last reply
        0
        • Sander RosselS Sander Rossel

          John Simmons / outlaw programmer wrote:

          On the "?" operator - I will strive NEVER to use that.

          Why? :confused:

          Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.

          Simplicity is prerequisite for reliability. — Edsger W. Dijkstra

          Regards, Sander

          realJSOPR Offline
          realJSOPR Offline
          realJSOP
          wrote on last edited by
          #28

          Because it obfuscates the code, and because I'm not yet coding in the appropriate version of .Net.

          ".45 ACP - because shooting twice is just silly" - JSOP, 2010
          -----
          You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
          -----
          When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013

          1 Reply Last reply
          0
          • C Chris Maunder

            I totally forgot about that! How about:

            #pragma on error resume next

            // ... code you wouldn't let your worst enemey near

            Mwahaha

            cheers Chris Maunder

            G Offline
            G Offline
            Gary Wheeler
            wrote on last edited by
            #29

            Who are you, and what have you done with that nice, wholesome Mr. Maunder?

            Software Zen: delete this;

            1 Reply Last reply
            0
            • F Foothill

              To those of who still use pointers (even in .Net), using (*) might be a little confusing but I have an idea. How about using a construct similar to the for loop

              // similar to...
              for (int i = 0; i < limit; ++i) { ... }

              // you can have
              NoThrow (var <out>; Func<T>; <result on throw>);

              // so your example becomes
              string result;
              NoThrow (result; dodgyApi.GetValue(); "I.M.Foo.Bar");

              if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

              Richard DeemingR Offline
              Richard DeemingR Offline
              Richard Deeming
              wrote on last edited by
              #30

              Foothill wrote:

              To those of who still use pointers (even in .Net), using (*) might be a little confusing

              And to those of us who use multiplication. :)


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

              1 Reply Last reply
              0
              • B BillWoodruff

                using System;

                namespace InMemoriamMaunder
                {
                public enum DodgyResult
                {
                ResultNull,
                ResultNonNull,
                ResultError
                }

                public static class Dodgy
                {
                    public static DodgyResult RunDodgy(ref T param, Func dodgyFunc)
                    {
                        try
                        {
                            param = dodgyFunc(param);
                
                            if (param == null)
                            {
                                return DodgyResult.ResultNull;
                            }
                            else
                            {
                                return DodgyResult.ResultOkay;
                            }
                        }
                        catch (Exception)
                        {
                             return DodgyResult.ResultError;
                        }
                    }
                }
                

                }

                Tests:

                private string SomeFuncError(string astring)
                {
                astring = null;
                return astring.ToString();
                }

                private string SomeFuncNull(string astring)
                {
                astring = null;
                return astring;
                }

                private string SomeFuncOkay(string astring)
                {
                astring = astring + astring;
                return astring;
                }

                string astring1 = "hello";
                string astring2 = null;
                string astring3 = "whatever";

                DodgyResult dr1 = Dodgy.RunDodgy(ref astring1, SomeFuncOkay);
                DodgyResult dr2 = Dodgy.RunDodgy(ref astring2, SomeFuncNull);
                DodgyResult dr3 = Dodgy.RunDodgy(ref astring3, SomeFuncError);

                Now, Chris, all you have left to do is boil this down to a single operator :)

                «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

                Richard DeemingR Offline
                Richard DeemingR Offline
                Richard Deeming
                wrote on last edited by
                #31

                How about something like this:

                public abstract class DodgyResult<T>
                {
                public abstract bool Succeeded { get; }
                public abstract T Value { get; }
                public abstract Exception Error { get; }

                public T GetValueOrDefault(T defaultValue = default(T))
                {
                    return Succeeded ? Value : defaultValue;
                }
                
                public static DodgyResult<T> Success(T value)
                {
                    return new SuccessResult(value);
                }
                
                public static DodgyResult<T> Failure(Exception error)
                {
                    return new ErrorResult(error);
                }
                
                // Explicit cast to the return type; 
                // throws an InvalidOperationException if this is a failure result:
                public static explicit operator T(DodgyResult<T> result)
                {
                    return result.Value;
                }
                
                // Allow the result to be treated as a bool value indicating success:
                public static bool operator true(DodgyResult<T> result)
                {
                    return result.Succeeded;
                }
                
                public static bool operator false(DodgyResult<T> result)
                {
                    return !result.Succeeded;
                }
                
                private sealed class SuccessResult : DodgyResult<T>
                {
                    public SuccessResult(T value)
                    {
                        Value = value;
                    }
                    
                    public override bool Succeeded => true;
                    public override T Value { get; }
                    public override Exception Error => null;
                }
                
                private sealed class ErrorResult : DodgyResult<T>
                {
                    public ErrorResult(Exception error)
                    {
                        Debug.Assert(error != null);
                        Error = error;
                    }
                    
                    public override bool Succeeded => false;
                    public override Exception Error { get; }
                    
                    public override T Value 
                    { 
                        // Wrap the error in a new exception to preserve the original stack trace:
                        get { throw new InvalidOperationException(Error.Message, Error); }
                    }
                }
                

                }

                public static class DodgyResult
                {
                // Helper to let the compiler infer the generic parameter:
                public static DodgyResult<T> Success<T>(T value)
                {
                return DodgyResult<T>.Success(value);
                }

                public static DodgyResult<T> RunDodgy<T>(Func<T> dodgyFunc)
                {
                    try
                    {
                        return Success(dodgyFunc());
                    }
                    catch (Exception ex)
                    {
                        return DodgyResult<T>.Failure(ex);
                

                "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                B 1 Reply Last reply
                0
                • C Chris Maunder

                  We get a shiny new "?" operator that takes

                  string result = null;
                  if (field != null)
                  {
                  result = field.Value;
                  }

                  and converts this to

                  string result = field?.Value

                  So what about the case where we're handling a flaky API

                  string result = null;
                  try
                  {
                  result = DodgyApi.GetValue(); // may throw an exception
                  }
                  catch
                  {
                  result = null;
                  }

                  What would you suggest we do for that? What about a headasplode (*) operator

                  string result = DodgyApi.GetValue*();

                  where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                  cheers Chris Maunder

                  D Offline
                  D Offline
                  Dan Neely
                  wrote on last edited by
                  #32

                  Why not make it a compiler flag that can be set once per file.

                  #pragma OnError ResumeNext

                  Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason? Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful? --Zachris Topelius Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies. -- Sarah Hoyt

                  C 1 Reply Last reply
                  0
                  • C Chris Maunder

                    We get a shiny new "?" operator that takes

                    string result = null;
                    if (field != null)
                    {
                    result = field.Value;
                    }

                    and converts this to

                    string result = field?.Value

                    So what about the case where we're handling a flaky API

                    string result = null;
                    try
                    {
                    result = DodgyApi.GetValue(); // may throw an exception
                    }
                    catch
                    {
                    result = null;
                    }

                    What would you suggest we do for that? What about a headasplode (*) operator

                    string result = DodgyApi.GetValue*();

                    where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                    cheers Chris Maunder

                    T Offline
                    T Offline
                    TheGreatAndPowerfulOz
                    wrote on last edited by
                    #33

                    Just NO!

                    #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                    1 Reply Last reply
                    0
                    • C Chris Maunder

                      We get a shiny new "?" operator that takes

                      string result = null;
                      if (field != null)
                      {
                      result = field.Value;
                      }

                      and converts this to

                      string result = field?.Value

                      So what about the case where we're handling a flaky API

                      string result = null;
                      try
                      {
                      result = DodgyApi.GetValue(); // may throw an exception
                      }
                      catch
                      {
                      result = null;
                      }

                      What would you suggest we do for that? What about a headasplode (*) operator

                      string result = DodgyApi.GetValue*();

                      where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                      cheers Chris Maunder

                      A Offline
                      A Offline
                      agolddog
                      wrote on last edited by
                      #34

                      Chris Maunder wrote:

                      string result = DodgyApi.GetValue*();

                      What about string result = DodgyApi.GetValue*(value); as you don't always want the type default. Not sure how we define my value for reference types, maybe it could use the C# new type { prop1 = val1, ...} paradigm? Anyway, no, bad idea. I want to fire people who silently swallow exceptions. At least, the code should be logging at some level, "hey, DodgyApi failed, using default value x" so that (in theory) somebody could investigate and make the api somewhat less dodgy.

                      1 Reply Last reply
                      0
                      • D Dan Neely

                        Why not make it a compiler flag that can be set once per file.

                        #pragma OnError ResumeNext

                        Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason? Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful? --Zachris Topelius Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies. -- Sarah Hoyt

                        C Offline
                        C Offline
                        Chris Maunder
                        wrote on last edited by
                        #35

                        I just love to imagine the absolute mayhem such a pragma would allow.

                        cheers Chris Maunder

                        1 Reply Last reply
                        0
                        • C Chris Maunder

                          We get a shiny new "?" operator that takes

                          string result = null;
                          if (field != null)
                          {
                          result = field.Value;
                          }

                          and converts this to

                          string result = field?.Value

                          So what about the case where we're handling a flaky API

                          string result = null;
                          try
                          {
                          result = DodgyApi.GetValue(); // may throw an exception
                          }
                          catch
                          {
                          result = null;
                          }

                          What would you suggest we do for that? What about a headasplode (*) operator

                          string result = DodgyApi.GetValue*();

                          where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                          cheers Chris Maunder

                          E Offline
                          E Offline
                          englebart
                          wrote on last edited by
                          #36

                          Don't use DodgyApi directly. string result = MyDodgyApiWrapper.GetValue(); Your wrapper can log any exceptions, provide a reasonable default value "Service unavailable. Try back later.", etc. If a better backend evolves later, just update your wrapper.

                          1 Reply Last reply
                          0
                          • N Nish Nishant

                            You could always write a helper method.

                            string GetString(int x)
                            {
                            throw new NotImplementedException();
                            }

                            void Foo()
                            {
                            string s = NoEx.Run(() => GetString(100));
                            Console.WriteLine(s == null);
                            }

                            class NoEx
                            {
                            public static T Run<T>(Func<T> method)
                            {
                            try
                            {
                            return method();
                            }
                            catch
                            {
                            return default(T);
                            }
                            }
                            }

                            Not as clean as syntactic sugar, but fairly close :-)

                            Regards, Nish


                            Website: www.voidnish.com Blog: voidnish.wordpress.com

                            H Offline
                            H Offline
                            Harley L Pebley
                            wrote on last edited by
                            #37

                            If you make Run an extension method and rename it to IgnoreExceptions for clarity, you can say:

                            var s = (() => GetString(100)).IgnoreExceptions();

                            You can go one further and add another parameterized type for the catch's use to only ignore certain types of exceptions:

                            var s = (() => GetString(100)).Ignore();

                            1 Reply Last reply
                            0
                            • C Chris Maunder

                              We get a shiny new "?" operator that takes

                              string result = null;
                              if (field != null)
                              {
                              result = field.Value;
                              }

                              and converts this to

                              string result = field?.Value

                              So what about the case where we're handling a flaky API

                              string result = null;
                              try
                              {
                              result = DodgyApi.GetValue(); // may throw an exception
                              }
                              catch
                              {
                              result = null;
                              }

                              What would you suggest we do for that? What about a headasplode (*) operator

                              string result = DodgyApi.GetValue*();

                              where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                              cheers Chris Maunder

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #38

                              Too much time on your hands?

                              C 1 Reply Last reply
                              0
                              • Richard DeemingR Richard Deeming

                                How about something like this:

                                public abstract class DodgyResult<T>
                                {
                                public abstract bool Succeeded { get; }
                                public abstract T Value { get; }
                                public abstract Exception Error { get; }

                                public T GetValueOrDefault(T defaultValue = default(T))
                                {
                                    return Succeeded ? Value : defaultValue;
                                }
                                
                                public static DodgyResult<T> Success(T value)
                                {
                                    return new SuccessResult(value);
                                }
                                
                                public static DodgyResult<T> Failure(Exception error)
                                {
                                    return new ErrorResult(error);
                                }
                                
                                // Explicit cast to the return type; 
                                // throws an InvalidOperationException if this is a failure result:
                                public static explicit operator T(DodgyResult<T> result)
                                {
                                    return result.Value;
                                }
                                
                                // Allow the result to be treated as a bool value indicating success:
                                public static bool operator true(DodgyResult<T> result)
                                {
                                    return result.Succeeded;
                                }
                                
                                public static bool operator false(DodgyResult<T> result)
                                {
                                    return !result.Succeeded;
                                }
                                
                                private sealed class SuccessResult : DodgyResult<T>
                                {
                                    public SuccessResult(T value)
                                    {
                                        Value = value;
                                    }
                                    
                                    public override bool Succeeded => true;
                                    public override T Value { get; }
                                    public override Exception Error => null;
                                }
                                
                                private sealed class ErrorResult : DodgyResult<T>
                                {
                                    public ErrorResult(Exception error)
                                    {
                                        Debug.Assert(error != null);
                                        Error = error;
                                    }
                                    
                                    public override bool Succeeded => false;
                                    public override Exception Error { get; }
                                    
                                    public override T Value 
                                    { 
                                        // Wrap the error in a new exception to preserve the original stack trace:
                                        get { throw new InvalidOperationException(Error.Message, Error); }
                                    }
                                }
                                

                                }

                                public static class DodgyResult
                                {
                                // Helper to let the compiler infer the generic parameter:
                                public static DodgyResult<T> Success<T>(T value)
                                {
                                return DodgyResult<T>.Success(value);
                                }

                                public static DodgyResult<T> RunDodgy<T>(Func<T> dodgyFunc)
                                {
                                    try
                                    {
                                        return Success(dodgyFunc());
                                    }
                                    catch (Exception ex)
                                    {
                                        return DodgyResult<T>.Failure(ex);
                                
                                B Offline
                                B Offline
                                BillWoodruff
                                wrote on last edited by
                                #39

                                Excellent. Thanks for this example, Richard !

                                «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

                                1 Reply Last reply
                                0
                                • N Nish Nishant

                                  You could always write a helper method.

                                  string GetString(int x)
                                  {
                                  throw new NotImplementedException();
                                  }

                                  void Foo()
                                  {
                                  string s = NoEx.Run(() => GetString(100));
                                  Console.WriteLine(s == null);
                                  }

                                  class NoEx
                                  {
                                  public static T Run<T>(Func<T> method)
                                  {
                                  try
                                  {
                                  return method();
                                  }
                                  catch
                                  {
                                  return default(T);
                                  }
                                  }
                                  }

                                  Not as clean as syntactic sugar, but fairly close :-)

                                  Regards, Nish


                                  Website: www.voidnish.com Blog: voidnish.wordpress.com

                                  B Offline
                                  B Offline
                                  BillWoodruff
                                  wrote on last edited by
                                  #40

                                  Very interesting Nish, I was puzzled by the omission of a Type argument to NoEx.Run, and realize that my habit of always writing out the Type arguments wasn't necessary in this case. I've made a note to try and find more information on exactly when the compiler can infer the Type which renders including the Type an option. thanks !

                                  «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

                                  1 Reply Last reply
                                  0
                                  • L Lost User

                                    Too much time on your hands?

                                    C Offline
                                    C Offline
                                    Chris Maunder
                                    wrote on last edited by
                                    #41

                                    ;)

                                    cheers Chris Maunder

                                    1 Reply Last reply
                                    0
                                    • C Chris Maunder

                                      We get a shiny new "?" operator that takes

                                      string result = null;
                                      if (field != null)
                                      {
                                      result = field.Value;
                                      }

                                      and converts this to

                                      string result = field?.Value

                                      So what about the case where we're handling a flaky API

                                      string result = null;
                                      try
                                      {
                                      result = DodgyApi.GetValue(); // may throw an exception
                                      }
                                      catch
                                      {
                                      result = null;
                                      }

                                      What would you suggest we do for that? What about a headasplode (*) operator

                                      string result = DodgyApi.GetValue*();

                                      where GetValue* will silently swallow the exception thrown by GetValue and return default. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?

                                      cheers Chris Maunder

                                      K Offline
                                      K Offline
                                      Kiriander
                                      wrote on last edited by
                                      #42

                                      Swallowing excepsions is bad style. If the function throws different exceptions, there may be strong need to react to them differently.

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups