【问题标题】:Use Exceptions in if condition在 if 条件下使用异常
【发布时间】:2019-09-19 18:33:20
【问题描述】:

我使用Firebase Auth 来管理我的登录和注册应用程序。

我想根据收到的异常添加 toast 消息。

例如,如果异常来自FirebaseAuthInvalidCredentialsException,我想敬酒一条消息。如果是来自FirebaseAuthUserCollisionException,那么我想再用一个吐司。

我使用类似的东西:

auth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    LayoutInflater inflater = LayoutInflater.from( SignUpActivity.this );
                    View toastview = inflater.inflate( R.layout.toast_registered, null );
                    Toast toast = new Toast( SignUpActivity.this );
                    toast.setView( toastview );
                    toast.setGravity( Gravity.CENTER, 0, 3 );
                    toast.setDuration( Toast.LENGTH_LONG );
                    toast.show();
                }

                if (!task.isSuccessful()) {
                    Toast.makeText(SignUpActivity.this, "toast1." + task.getException(),
                            Toast.LENGTH_SHORT).show();
                }

                if (!task.isSuccessful()) {
                    Toast.makeText(SignUpActivity.this, "toast2." + task.getException(),
                            Toast.LENGTH_SHORT).show();
                } else {
                    startActivity(new Intent(SignUpActivity.this, MainActivity.class));
                    finish();
                }
            }
        });

所以基本上我需要在 if 条件中添加一些东西,但是我不确定是什么。

我看到catch 的用法,但我不认为是这种情况。

谢谢

【问题讨论】:

  • 如果身份验证失败,您将在此处显示 2 个祝酒词。请参阅我的回答,它处理您在问题中陈述的每个失败案例一次且仅一次,并删除冗余检查。在我的回答中,我假设您只想在身份验证失败时启动 SignupActivity。

标签: java exception firebase-authentication


【解决方案1】:

应该这样做:

auth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    LayoutInflater inflater = LayoutInflater.from( SignUpActivity.this );
                    View toastview = inflater.inflate( R.layout.toast_registered, null );
                    Toast toast = new Toast( SignUpActivity.this );
                    toast.setView( toastview );
                    toast.setGravity( Gravity.CENTER, 0, 3 );
                    toast.setDuration( Toast.LENGTH_LONG );
                    toast.show();
                }
                else {
                    if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                         Toast.makeText(SignUpActivity.this, "toast1." + task.getException(),
                         Toast.LENGTH_SHORT).show();
                    }
                    else if (task.getException() instanceof FirebaseAuthUserCollisionException) {
                         Toast.makeText(SignUpActivity.this, "toast2." + task.getException(),
                            Toast.LENGTH_SHORT).show();
                    }   
                    startActivity(new Intent(SignUpActivity.this, MainActivity.class));
                    finish();
                }
            }
        });

因此,您检查任务是否成功,如果不是,则在开始注册活动和完成此活动之前打开错误类型并显示相应的 toast。

【讨论】:

  • 对不起,是instanceof,现在更新我的答案(不是Of中的小写o)
  • Java中的关键字,用于检查变量是否为类的实例
  • 是可能发生的仅有的两个例外吗?如果没有,或者如果他们添加了第三个,你应该有另一个 else 作为一个包罗万象,否则用户将看不到任何 toast。
  • 不保证,所以你提出了一个很好的观点。对于 OP - 正如大卫所说;始终检查边缘情况 - 在这种情况下,这是一般异常。但由于 OP 问题特别是关于 2 种异常类型,我的回答应该解决这个问题。
  • 无论如何这都是域逻辑,也许有理由在一般情况下不显示敬酒?我的回答应该解决 OP 问题的症结
【解决方案2】:

首先,您只需要一个条件,例如 task.isSuccessful()。

你可以这样做:

if(task.isSuccessful()) {
    try {
        throw task.getException();
    } catch(FirebaseAuthInvalidCredentialsException e) {
        /*Toast here*/
    } catch(FirebaseAuthUserCollisionException e) {
        /*Toast here*/
    } catch(...) ...
}

...
throw task.getException();
...

您将抛出特定的异常并使用

} catch(FirebaseAuthInvalidCredentialsException e) {
    /*Toast here*/
}

您将捕获特定的异常来处理它并做您想做的事情,在您的情况下,您将编写代码以在 catch 语句中显示 toast。

记住要捕获所有异常,否则当抛出未处理的异常时,您的应用将崩溃。

你也可以处理泛型异常:

if(task.isSuccessful()) {
    try {
        throw task.getException();
    } catch(FirebaseAuthInvalidCredentialsException e) {
        /*Toast here*/
    } catch(FirebaseAuthUserCollisionException e) {
        /*Toast here*/
    } catch(Exception e) {
        /*Handle generic exception*/
    }
}

再见

【讨论】:

  • 到底为什么要尝试抛出已经在底层框架中抛出并捕获的异常?
  • 你也不需要检查 !isSuccessful(),因为根据定义,第一个检查检查的是 this 的反函数,所以你可以使用 else...
  • @ThomasCook 是的,抱歉,我刚刚从答案中复制了代码。反正我不喜欢使用多个条件,我觉得try-catch清晰易读。
  • 很抱歉,这真是个糟糕的建议。您正在执行一个尝试,其唯一目的是抛出一个已经捕获的异常,以便使用 catch 机制执行完全可以使用 instanceof 的类型检查。
  • 尝试应该做一些可能失败的事情,而不是做一些失败的事情。有点像“尝试”这个名字。该框架已经“尝试”完成了有风险的工作,甚至已经竭尽全力在传递给回调的值中封装失败,因此您可以避免在消费端使用 try catch
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多