[fix] emit error instead of throw in async context