创建Java异常子类以呈现自定义消息

huangapple go评论70阅读模式
英文:

Create Java Exception subclass to present custom message

问题

我有一个安全包,在其中类文件共享通用的Exception

	catch (InvalidKeyException | NoSuchAlgorithmException e) {
      		System.err.println("Key Exception: Invalid key is detected to sign or verify signature.\n");
      	} catch (UnrecoverableKeyException e) {
      		System.err.println("Key Exception: Faulty key can not be used to sign signature.\n");
      	} catch (KeyStoreException e) {
	        System.err.println("KeyStore Exception: key Store may be faulty.\n");
……………

我尝试DSCoreException,它可以根据对象的getLocalizedMessage()结果抛出自定义描述性消息,不包括异常类名。

实现的要点是:

catch (Exception e) {
  throw new DSCoreException(e);
} 
…………………..
class DSCoreException extends Exception {
  DSCoreException(Exception s) { 
    	super(s.getLocalizedMessage());
    	if (super.getLocalizedMessage().contains("Signature not available")) {
    		System.err.println("Key Exception: Invalid key algorithm is used to sign signature.\n");
    	}
}

它产生了:

Key Exception: Invalid key algorithm is used to sign signature. 

Exception in thread "main" com.fc.security.DSCoreException: SHA512withDSA Signature not available
	at com.fc.security.TestException.main(TestException.java:91)

我的期望是:

Key Exception: Invalid key algorithm is used to sign signature. 

如何只显示我的自定义消息?(在if之后会有else-if

英文:

I have security package in which the class files share the common Exceptions:

	catch (InvalidKeyException | NoSuchAlgorithmException e) {
      		System.err.println("Key Exception: Invalid key is detected to sign or verify signature." + " \n");
      	} catch (UnrecoverableKeyException e) {
      		System.err.println("Key Exception: Faulty key can not be used to sign signature." + " \n");
      	} catch (KeyStoreException e) {
	        System.err.println("KeyStore Exception: key Store may be faulty." + " \n");
……………

I attempt the DSCoreException which can throw back custom descriptive messages based on the object's getLocalizedMessage() result, excluding the exception class name.
The gist of the implementation is:

catch (Exception e) {
  throw new DSCoreException(e);
} 
…………………..
class DSCoreException extends Exception {
  DSCoreException(Exception s) { 
    	super(s.getLocalizedMessage());
    	if (super.getLocalizedMessage().contains("Signature not available")) {
    		System.err.println("Key Exception: Invalid key algorithm is used to sign signature." + " \n");
    	}
}

It produces:

Key Exception: Invalid key algorithm is used to sign signature. 

Exception in thread "main" com.fc.security.DSCoreException: SHA512withDSA Signature not available
	at com.fc.security.TestException.main(TestException.java:91)

My expectation is:

Key Exception: Invalid key algorithm is used to sign signature. 

How can I display only my custom message? (There will be else-if following the if)

答案1

得分: 2

您的异常类应该像这样:

class DSCoreException extends Exception {
    DSCoreException(String msg) {
        super(msg);
    }
    ...更多需要的内容...
}

然后,您可以使用异常处理程序来替换特定异常:

try {
    do_something_here();
} 
catch (Exception ex) {  // 注意应该是更狭窄的类
    if (ex.getLocalizedMessage().contains("Signature not available"))             
        ex = new DSCoreException("Key Exception: Invalid key algorithm is used to sign signature."); 
    throw ex;
}

或者,根据您的整体需求,稍微不同的方式:

try {
    do_something_here();
} 
catch (Exception ex) {  // 注意应该是更狭窄的类
    String msg = ex.getLocalizedMessage();
    if (msg.contains("Signature not available"))             
        msg = "Key Exception: Invalid key algorithm is used to sign signature."; 
    throw new DSCoreException(msg);
}

这两种方式都会捕获异常,检查异常类型,然后在重新抛出异常之前可选地替换它。

在这里的基本教训是,异常是一种控制流设备,而不仅仅是打印错误的工具。即使在您打算显示消息的简单情况下,异常也是将错误条件信息传递给将要显示它的代码的一种方法;异常本身不应该执行显示操作。

英文:

You have an Exception that prints messages. That is not the job of an Exception.

An Exception is supposed to provide enough information to describe the exception it's reporting. For example, it will typically have a message string.

If some code catches that Exception, it can (if it chooses) display the message string. But the Exception class never should.

Your exception class should look like:

 class DSCoreException extends Exception {
      DSCoreException(String msg) {
          super(msg);
      }
      ... more needed here ...
 }

and then maybe you have an exception handler to replace particular exceptions by your own exception.

  try {
      do_something_here();
  } 
  catch (Exception ex) {  // NOTE really ought to be a narrower class
      if (ex.getLocalizedMessage().contains("Signature not available"))             
          ex = new DSCoreException("Key Exception: Invalid key algorithm is used to sign signature."); 
      throw ex;
  }

You catch the exception, examine it to see what it is, and optionally replace it with a better exception before re-throwing it.

A slightly different twist, depending on your overall needs:

  try {
      do_something_here();
  } 
  catch (Exception ex) {  // NOTE really ought to be a narrower class
      String msg = ex.getLocalizedMessage();
      if (msg.contains("Signature not available"))             
          msg = "Key Exception: Invalid key algorithm is used to sign signature."; 
      throw new DSCoreException(msg);
  }

That one always throws a DSCoreException but possibly replaces the message. This converts all exceptions into 'your' class, which may have benefits to whoever is calling your code.

The underlying lesson here is that an exception is a control-flow device, not just a thing that prints errors. Even in the simple case where you intend to display the message, the exception is a way to get the error condition info to the code that is going to display it; the exception should not itself do the displaying.

An objection raised, in a comment now deleted, was that the catcher of an exception could obtain a stack trace and thereby reveal information such as package names. The OP apparently wants to prevent this, though I don't see why. That boils down to wanting an Exception to not behave like an Exception. You can't control this in any reasonable way.

huangapple
  • 本文由 发表于 2020年8月11日 03:47:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63347025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定