Javascript multiple “try”s

后端 未结 3 591
不思量自难忘°
不思量自难忘° 2021-01-14 04:53

We all know the basic escaping mechanism in JS:

try {
    ...
}
catch(err) {
    ..
}

I have a JSON data in which I want to check if a lead

相关标签:
3条回答
  • 2021-01-14 04:59

    Besides the fact that 2 years later, but with support of Babeljs even before, the best fitting solution should be based on Optional chaining, this Q remains a perfect target for practicing entirely function based approaches.

    Implementing e.g. an afterThrowing method modifier could result in an expression as short and as close as to the OP's pseudo code ...

    try {
      name = lead['Meta']['Name']['Full'];
    } else try {
      name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
    } catch (e) {
      name = 'No Name';
    }
    

    ... then would turn into something like ...

    function getFullName(lead) {
      return lead['Meta']['Name']['Full'];
    }
    function getComposedFullName(lead) {
      return lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
    }
    
    const name = (getFullName.afterThrowing((error, [data] = args) =>
    
      (getComposedFullName.afterThrowing((/*error,[data]=args*/) => 'No Name')(data))
    
    )(lead));
    

    ... implementation and example code as proof of concept ...

    const leadTestSample = {
      success: {
        fullName: {
          Meta: {
            Name: {
              Full: "Mary Jane Doe"
            }
          }
        },
        composed: {
          Details: {
            Name: {
              First: "Jane",
              Last: "Doe"
            }
          }
        }
      },
      failure: {
        Meta: {},
        Details: {}
      }
    };
    
    
    function getFullName(lead) {
      return lead['Meta']['Name']['Full'];
    }
    function getComposedFullName(lead) {
      return lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
    }
    const nameDefault = 'No Name';
    
    
    /*
    try {
      name = lead['Meta']['Name']['Full'];
    } else try {
      name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
    } catch (e) {
      name = 'No Name';
    }
    */
    
    const fullNameData = leadTestSample.success.fullName;
    const composedData = leadTestSample.success.composed;
    const failureData = leadTestSample.failure;
    
    console.log(
      (getFullName.afterThrowing((error, [data] = args) =>
    
        (getComposedFullName.afterThrowing(() => nameDefault)(data))
    
      )(fullNameData))
    );
    console.log(
      (getFullName.afterThrowing((error, [data] = args) =>
    
        (getComposedFullName.afterThrowing(() => nameDefault)(data))
    
      )(composedData))
    );
    console.log(
      (getFullName.afterThrowing((error, [data] = args) =>
    
        (getComposedFullName.afterThrowing(() => nameDefault)(data))
    
      )(failureData))
    );
    .as-console-wrapper { min-height: 100%!important; top: 0; }
    <script>
      (function (Function) {
    
        const fctPrototype = Function.prototype;
        const FUNCTION_TYPE = (typeof Function);
    
        function isFunction(type) {
          return (
               (typeof type == FUNCTION_TYPE)
            && (typeof type.call == FUNCTION_TYPE)
            && (typeof type.apply == FUNCTION_TYPE)
          );
        }
        function getSanitizedTarget(target) {
          return ((target != null) && target) || null;
        }
    
        function afterThrowing/*Modifier*/(handler, target) {
          target = getSanitizedTarget(target);
    
          const proceed = this;
          return (
    
            isFunction(handler) &&
            isFunction(proceed) &&
    
            function () {
              const context = target || getSanitizedTarget(this);
              const args = arguments;
    
              let result;
              try {
                result = proceed.apply(context, args);
    
              } catch (exception) {
    
                result = handler.call(context, exception, args);
              }
              return result;
            }
    
          ) || proceed;
        }
        // afterThrowing.toString = () => 'afterThrowing() { [native code] }';
    
        Object.defineProperty(fctPrototype, 'afterThrowing', {
          configurable: true,
          writable: true,
          value: afterThrowing/*Modifier*/
        });
    
      }(Function));
    </script>

    I wouldn't mind if, at one day, JavaScript officially features ... Function.prototype[before|after|around|afterThrowing|afterFinally].

    0 讨论(0)
  • 2021-01-14 04:59

    Instead of do this in using one try-catch block only. As we know when we will get type error in javascript when access something that does not exist.

    See the below code snippet.

    function getName(isFullName='true'){
    
      try{
         if(isFullName)
           name = lead['Details']['Name']['Full'];       
         else
           name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];       
         }
       catch(e){
         if (e instanceof TypeError && isFullName) 
             getName(false);
         name = 'No name';   
        }
    } 
    

    In case name is full name is coming undefined then, we need to add an extra if block to check for the undefined case.

    0 讨论(0)
  • 2021-01-14 05:11

    You could nest your second try/catch block in the exception block of the first try/catch block as follows:

    try {
        name = lead['Details']['Name']['Full'];
    } catch(ex0) {      
      try {
          name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
      } catch (ex1) {
          name = "No Name";
      }
    }
    

    This is valid syntax, and functionally equivalent to what you're requiring

    0 讨论(0)
提交回复
热议问题