从FiRestore获取文档时的错误处理 [英] Error handling when getting document from Firestore

查看:17
本文介绍了从FiRestore获取文档时的错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在具有FireStore和angularFire2的角度5中,通过控制器从服务获取文档时处理错误的正确方法是什么?

服务:

getInviteById( inviteId: string ): Promise<any> {    

    // get requested invite from firestore  
    var inviteDocument = this.afs.collection( 'invites' ).doc( inviteId );
    let invite = inviteDocument.ref.get().then( doc => {

        // if document exists
        if (doc.exists) {

            // return id and data
            const id = doc.id; 
            var data = doc.data() as any;
            return { id, ...data };

        // if document does not exist
        } else {
            console.log("Error: No such document!");

            // WHAT DO I NEED TO RETURN HERE???
        }

    // if other error
    }).catch(function(error) {
        console.log("Error: Getting document:", error);                            

        // WHAT DO I NEED TO RETURN HERE???
    });

    // return invite
    return invite;
};

控制器:

this.inviteService.getInviteById( inviteId )
    .then( resolve => {
        this.invite = resolve;
    })
    .catch( err => {
            // THIS NEVER GETS CALLED !
            console.log("INVITE-COMPONENT: Cannot get invite for this id." );
    });
如果FireStore中存在带有invite-id的文档,则一切正常。但是,如果FireStore中没有针对邀请id的文档,则该服务将记录"错误:没有这样的文档!"(如预期),但组件不会进入自己的catch大小写。

如何处理组件中的"没有这样的文档"错误,以便可以相应地修改我的用户界面?

推荐答案

您可以退回已拒绝的承诺,但throw更简单。

因此,简单地说,您可以这样写:

// (1) ILLUSTRATIVE - NOT YET THE FULL SOLUTION
getInviteById(inviteId: string): Promise<any> {
    var inviteDocument = this.afs.collection('invites').doc(inviteId);
    return inviteDocument.ref.get()
    .then(doc => {
        if (doc.exists) { // if document exists ...
            const id = doc.id;
            var data = doc.data() as any;
            return {id, ...data}; // ... return id and data.
        } else { // if document does not exist ...
            throw new Error('No such document!'); // ... throw an Error.
        }
    })
    .catch(error => {
        throw new Error('Error: Getting document:'); // throw an Error
    });
};
但是,内部的throw会立即被外部的.catch()捕获,并且‘No That Document!’错误消息将丢失,并显示为"Error:Geting Document:"。

可以通过如下方式调整整体模式来避免损失:

// (2) ILLUSTRATIVE - NOT YET THE FULL SOLUTION
getInviteById(inviteId: string): Promise<any> {
    var inviteDocument = this.afs.collection('invites').doc(inviteId);
    return inviteDocument.ref.get()
    .catch(error => { // .catch() error arising from inviteDocument.ref.get()
        throw new Error('Error: Getting document:');
    })
    .then(doc => {
        if (doc.exists) {
            const id = doc.id;
            var data = doc.data() as any;
            return {id, ...data};
        } else {
            throw new Error('No such document!'); // can now be caught only by getInviteById's caller
        }
    });
};

然而,即使这样也是不正确的,因为存在以下可能性:

  1. this.afs.collection('invites').doc(inviteId)可能返回null,在这种情况下应引发错误。
  2. this.afs.collection('invites').doc(inviteId)inviteDocument.ref.get()可能会同步引发

在任何一种情况下,调用方都有权期望承诺返回函数始终异步引发,而不管错误是如何/在哪里发生的。

可以通过确保从Promise链内部执行var inviteDocument = this.afs.collection('invites').doc(inviteId);inviteDocument.ref.get()并正确处理null案例来克服该问题,如下所示:

// (3) SOLUTION
getInviteById(inviteId: string): Promise<any> {
    return Promise.resolve() // neutral starter promise 
    .then(() => {
        var inviteDocument = this.afs.collection('invites').doc(inviteId); // now executed inside promise chain
        if(inviteDocument) {
            return inviteDocument.ref.get(); // now executed inside promise chain.
        } else {
            throw new Error(); // no point setting an error message here as it will be overridden below.
        }
    })
    .catch(error => {
        throw new Error('Error: Getting document:');
    })
    .then(doc => {
        if (doc.exists) {
            const id = doc.id;
            var data = doc.data() as any;
            return {id, ...data};
        } else {
            throw new Error('No such document!');
        }
    });
};

调用方(您的控制器)将捕获并记录getInviteById()产生的任何错误:

this.inviteService.getInviteById(inviteId)
.then(result => { // better not to name the variable `resolve`
    this.invite = result;
})
.catch(err => {
    console.log("INVITE-COMPONENT: Cannot get invite for this id: " + error.message);
});

备注

  1. console.log()getInviteById()内是不必要的(可能调试时除外)。调用方的.catch()将执行所有必要的日志记录。

这篇关于从FiRestore获取文档时的错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆