Ответ 1
В отличие от исключений в синхронном коде, которые становятся неактивными, как только код возвращается в режим ожидания, браузер обычно не знает логического конца цепочки обещаний, в котором асинхронная ошибка может считаться неотображаемой. Цепочки динамически собираются в конце концов и поэтому лучше заканчиваются с окончательным .catch
на логическом конце цепи, то есть асинхронным эквивалентом простоя.
Наличие окончательного .catch(e => console.error(e))
кажется мне очень разумным, но вы правы, что браузеры имеют тенденцию отображать эти ошибки по-другому, чем неотображаемые исключения. Если вы хотите, чтобы они отображались одинаково, вы можете использовать этот трюк:
.catch(e => setTimeout(() => { throw e; }))
Это бросит e
, содержащий исходную трассировку стека и номер строки, в следующем цикле и за пределами цепочки обещаний, где ничто не поймает его, и оно будет сообщено как неотображенное. Мы используем setTimeout
для преодоления поведения по умолчанию .catch
, которое должно фиксировать любые исключения в цепочке в случае, если вы намерены продолжать цепочку.
С этим, надеюсь, вы видите, что любое различие между "логическими" и другими ошибками не имеет значения. Любая ошибка, которая делает ее к хвосту цепочки, была фатальной для цепочки, то есть неотображенной (хотя, конечно, вы можете сортировать "логические" из других ошибок в конечном улове и отображать их по-разному, если вы выберете.)