在catch中调用未定义的方法编译运行无法捕获报错
=========================

#### 问题现象

定义了一个异步函数，使用try-catch来捕获可能出现的异常，如果在catch中调用未定义的方法，代码能正常编译，运行时也没有任何错误提示，但是catch之后的代码不会执行。问题代码示例参考如下：

export async function getLocalImgOrientation(oriFilePath: string) : Promise<number\> {
  let orientation \= '';
  try {
    Logger.info('try called');
    let file \= fs.openSync(oriFilePath, fs.OpenMode.READ\_ONLY);
    let imageSource: image.ImageSource \= image.createImageSource(file.fd);
    orientation \= await imageSource.getImageProperty(image.PropertyKey.ORIENTATION);
  } catch (e) {
    Logger.info('catch called');
   _ // sayHello()是一个没有声明和定义的不存在的函数，但是编译不会报错_
    e.sayHello();
  }

  _// 此处日志不会被打印_
  Logger.info('tag one');
  let rotate: number \= 0;
  if (orientation.length \> 0) {
    rotate \= 90;
  }
  return rotate;
}

调用代码示例参考如下：

Button('异步任务中调用不存在函数')
  .onClick(() \=\> {
   _ // 传入一个错误参数，模拟发生异常_
    let path \= 'empty';
    getLocalImgOrientation(path).then((r: number) \=\> {
      Logger.info(\`r is ${r}\`);
    })
  })

#### 背景知识

[async/await](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/async-concurrency-overview#asyncawait)：基于Promise的语法糖，async函数本身并不会直接定义微任务，但它内部的异步操作（尤其是await后面的代码）会以微任务的形式执行。

#### 解决方案

异常发生时，catch的参数e类型为any，此时调用了未定义的函数编译器无法报错属于正常现象。async函数内部的异步任务是以微任务的形态执行的，执行失败不会导致整个进程crash，也不会导致运行报错。可以通过在调用的外层函数处增加catch来捕获报错。

_//_ _传入一个错误参数，模拟发生异常_
let path \= 'empty';
getLocalImgOrientation(path).then((r: number) \=\> {
  console.info(\`r is ${r}\`);
}).catch((e: BusinessError) \=\> {
  console.error(\`code: ${e.code}, ${e.message}\`);
});

运行后控制台会打印错误日志“code: undefined, undefined is not callable”。

完整示例参考如下：

import fs from '@ohos.file.fs';
import { image } from '@kit.ImageKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('异步任务中调用不存在函数')
        .onClick(() \=\> {
        _  // 传入一个错误参数，模拟发生异常_
          let path \= 'empty';
          getLocalImgOrientation(path).then((r: number) \=\> {
            console.info(\`r is ${r}\`);
          }).catch((e: BusinessError) \=\> {
            console.error(\`code: ${e.code}, ${e.message}\`);
          });
        });
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center);
  }
}

async function getLocalImgOrientation(oriFilePath: string): Promise<number\> {
  let orientation \= '';
  try {
    console.info('try called');
    let file \= fs.openSync(oriFilePath, fs.OpenMode.READ\_ONLY);
    let imageSource: image.ImageSource \= image.createImageSource(file.fd);
    orientation \= await imageSource.getImageProperty(image.PropertyKey.ORIENTATION);
  } catch (e) {
    console.info('try called');
  _  // sayHello()是一个没有声明和定义的不存在的函数，但是编译不会报错_
    e.sayHello();
  }

 _ // 此处日志不会被打印_
  console.info('tag');
  let rotate: number \= 0;
  if (orientation.length \> 0) {
    rotate \= 90;
  }
  return rotate;
}