How to handle exceptions in nested async functions which use 'await'

I have a situation like this:

let obj = new MyObj()
obj.init()
.then(async () => {
    try {
        const items = await obj.getItems()
    } catch(error) {
        console.log(error.message)
    }
})

and then getItems:

getItems() {
    let items = []

    this.itemIdList.forEach(async id => {
        try {
            const itemInfoList = await this.getItemInfo(id)

            if(itemInfoList) {
                itemInfoList.forEach(item => {
                   items.push(item.name)
                })
            }

        } catch(error) {
            //can't do this: throw error
            console.log(error.message
        }
    })

    return items
}

If an exception is thrown in the call from this.getItemInfo(id), it's handled correctly and gets caught. But if I want the outer promise to handle the error, I thought I could rethrow the error (as you can see in the comment above), but I still get UnhandledPromiseRejection exception and it never gets caught. When I remove the 'throw error', the exception is squashed (of course) and the outer promise will never see the error. How can I handle all exceptions from the inner to the outer?