Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor and Improve Exception Handling #115

Merged
merged 18 commits into from
Jun 16, 2024

Conversation

mitsuki31
Copy link
Owner

@mitsuki31 mitsuki31 commented Jun 16, 2024

Overview

This pull request refactors and improves the exception handling functionality within the JMatrix library. It introduces new capabilities, updates Javadocs, and enhances the existing exception-raising mechanisms. These changes aim to provide more robust error handling, configurable auto-raise behavior, and comprehensive documentation to assist developers in effectively managing exceptions in their applications.

Changes Made

  • Enum for Error Codes

    • Added the JMErrorCode enum to represent error codes within the JMatrix library. Each error code is associated with an integer, a string representation, and a descriptive message.
  • Auto-Raise Configuration

    • Introduced the ability to configure auto-raise behavior via system properties and environment variables. This allows for dynamic control over whether exceptions should print stack traces and exit the application or be thrown back for handling in try-catch blocks.
  • Exception Handling Refactor

    • Refactored the exception-raising mechanism in the Matrix class to use the JMatrixBaseException.raise method, replacing the previous JMatrixUtils.raiseError method. This change provides configurable auto-raise exceptions, allowing developers to choose appropriate error-handling strategies.
  • Serial Version UID Update

    • Changed the serialVersionUID values for all non-deprecated exceptions to a new format that includes the publication date and error code.
  • JMatrixBaseException Enhancements

    • Updated the JMatrixBaseException class to include new features such as configurable auto-raise behavior using environment variables or system properties.
    • Improved the toString and getMessage methods to ensure they do not return null.
    • Refactored the printStackTrace method to print all available stack traces for easier error source identification.
    • Added new constructors to handle various initialization scenarios and prevent NullPointerException.
  • Subclass Refactors

    • Refactored all JMatrixBaseException subclasses to align with the new superclass changes, removing unnecessary fields and refining methods for consistency.
  • Documentation Fixes and Updates

    • Resolved bad link tags and paragraph formatting issues in existing documentation.
    • Updated Javadocs for various methods and classes, ensuring accuracy and completeness.

Description

This pull request addresses several key areas to improve the robustness and usability of exception handling in the JMatrix library. Here are the detailed descriptions of the improvements:

Enum for Error Codes

Introduced the JMErrorCode enum to standardize error codes within the JMatrix library. Each error code in the enum is associated with an integer, a string representation, and a descriptive message. This standardization simplifies error handling and enhances code readability.

Enum Constant Error Number Default Error Message
INVIDX 201 "Given index is out of bounds"
INVTYP 202 "Matrix has invalid type of matrix"
NULLMT 203 "Matrix is null"
UNKERR 400 "Unknown error"

Exception Improvements and Refactors

  • Replaced the JMatrixUtils.raiseError method with the new JMatrixBaseException.raise method in the Matrix class. The raise method was introduced to enhance the throw statement to more configurable by users and developers, the method will behaves like throw keyword when the auto-raise configuration set to manual (this can be configured using system property and environment variable), throwing exceptions for traditional try-catch handling. Otherwise, it will prints the stack traces and exit the application immediately which is the default behavior of the raise method.

  • Added new constructors to handle various exception initialization scenarios, they are:

    public JMatrixBaseException(int, String);
    public JMatrixBaseException(String, Throwable);
    protected JMatrixBaseException(String, Throwable, boolean, boolean);
  • Improved the toString and getMessage methods to ensure they do not return null, relying to the exception messages from JMErrorCode enum if the error message was not provided or null.

  • Refactored the printStackTrace method to print all available stack traces, making it easier for developers to trace and identify the source of errors.

  • Introduced new methods such as getErrorCode, which returns the JMErrorCode associated with the exception, and getCause, which returns the causative exception.

  • Refactored subclasses such as InvalidIndexException, IllegalMatrixSizeException, and NullMatrixException to align with the new superclass changes. These refactors removed unnecessary fields, refined methods, and ensured compatibility with the updated JMatrixBaseException class.

Auto-Raise Configuration

The auto-raise exceptions has been utilized by this library since the JMatrixUtils.raiseError method was introduced, this behavior makes any exceptions passed to the method will be printed and then exit the application immediately. This makes it harder for developers to handle the thrown exceptions.

These changes here introduced a new feature to configure the auto-raise exceptions behavior both from system property and environment variable. Users and developers can configure the behavior of auto-raise by set either the system property jm.autoraise or environment variable jm_autoraise to specific known values.

To deactivate the auto-raise behavior, set the value to one of these known values:

  • manual or simply m
  • no or simply n

To activate the auto-raise behavior, set the value to one of these known values:

  • auto or simply a
  • yes or simply y

Note

If both the system property jm.autoraise and environment variable jm_autoraise are set, the system property takes precedence. It is RECOMMENDED to configure using system property instead environment variable if possible.

The default configuration of auto-raise behavior is auto, which you might not have to configure and set the auto-raise configuration to auto or yes.

Example Usage

Using System Property

From command-line:

java -Djm.autoraise=manual -cp /path/to/jmatrix.jar Foo.java

During runtime execution (dynamic update):

// Set the auto-raise configuration to manual
System.setProperty("jm.autoraise", "manual");
Using Environment Variable

UNIX:

export jm_autoraise=manual
java -cp /path/to/jmatrix.jar Foo.java

Windows:

$env:jm_autoraise=manual
java -cp \path\to\jmatrix.jar Foo.java

Warning

You might encountering an ExceptionInInitializerError with IllegalArgumentException as cause exception during runtime execution, this exception was due to passing an unknown value to auto-raise configuration.

Deactivating the auto-raise configuration allows developers to handle exceptions using traditional try-catch blocks, providing more control over application flow and error handling.

In addition to this feature addition, within the internal context we also introduced new methods, getRaiseConfig and getRaiseConfigFromSystemProps, to safely retrieve the auto-raise configuration from environment variables and system properties, respectively. These methods handles SecurityException gracefully by logging a warning message instead of throwing an exception.

Serial Version UID Update

Updated the serialVersionUID values for all non-deprecated exceptions to a new format. The new format 430{dd}{MM}{YYYY}{EEE} includes the publication date and error code, where:

  • {dd} is the day
  • {MM} is the month
  • {YYYY} is the year the project was published on GitHub, and
  • {EEE} is the error code from the JMErrorCode enum.

This format ensures that each serialVersionUID is unique and meaningful.

Documentation Improvements

Enhanced the Javadocs for several methods of exception classes to provide detailed descriptions, usage scenarios, cross-references, and detailed exception conditions. This ensures that developers have a comprehensive understanding of the method's functionality and usage.

Summary

This pull request significantly enhances the exception handling capabilities of the JMatrix library. It introduces configurable auto-raise behavior, updates Javadocs for clarity and completeness, and refactors existing exception mechanisms for robustness. These changes provide developers with more control over error handling, improve documentation, and ensure the library's reliability in managing exceptions.

By addressing these key areas, the pull request aims to make the JMatrix library more robust, flexible, and developer-friendly, supporting better error handling practices and improving overall code quality.

The `JMErrorCode` enum represents error codes for various error conditions that can occur within a JMatrix library. Each error code is associated with an integer error number, a string representation of the error code, and a descriptive error message.
Added several new constructors to `JMatrixBaseException` class:
  - JMatrixBaseException(int, String)
  - JMatrixBaseException(String, Throwable)
  - JMatrixBaseException(String, Throwable, boolean, boolean)

This includes some enhancements and refactors to existing constructors, maintaining their functionality. In addition, private fields to store the stack traces has been removed.
* Defined several private and protected fields used by `printStackTrace`
* Introduced a new method called `getErrorCode`, returns the `JMErrorCode` object associated with this throwable
* Introduced a new method called `getCause`, returns the causative exception of this throwable, if the cause exception is a reference of this throwable, then returns `null`
* Refactored the `toString` and `getMessage` methods to compatible with new features (`JMErrorCode`)
* Added a new overload of `printStackTrace` method that accepts a `PrintStream` object
* Refactored the `printStackTrace()` method and moved its implementation to `printStackTrace(PrintStream)` method
Changed the error number (errno) of `JMErrorCode.UNKERR` from 200 to 400.

Related commit: 789f141
The method will returns a string representation of the corresponding enum with format `<CODE>[<ERRNO>]`. For instance, the `NULLMT` error code will gives `NULLMT[203]`.
Added documentation for the thrown exception (IllegalArgumentException) in the `JMErrorCode.toString()` method.
Refactored several constructors of `JMatrixBaseException` to prevent throwing a NullPointerException due to error code is `null`. In addition to this change, added Javadoc to every undocumented constructors with details description.
* Refactored both the `toString` and `getMessage` methods to prevent from returning a `null` value
* Refactored the `printStackTrace` method to make it prints all available stack traces within, this makes developer to read and find the source error easily
Added a new capability to raise an exception, this feature have similar behavior with the existing method `JMatrixUtils.raiseError` but this can be configured by users. To configure, users only need to define an environment variable called "jm.raise". with values as follows:
  - `auto`, `a`, `yes`, `y` : This will set the internal configuration to `auto`, which means when calling the `JMatrixBaseException.raise` method, it will prints the stack traces of the given throwable and exits with specified (or determined automatically) error number
  - `manual`, `m`, `no`, `n` : This will set the internal configuration to `manual`, which means when calling the `JMatrixBaseException.raise` method, it will throws back the given throwable and will never exits the application.

This behavior supports scenarios where the application or users prefers to handle exceptions using traditional try-catch blocks rather than exiting.
Refactored all `JMatrixBaseException` subclasses to compatible with the new changes in their super class (JMatrixBaseException). This includes, removing unecessary fields and refining several methods.

List of classes that being refactored in this change:
  - InvalidIndexException
  - IllegalMatrixSizeException
  - NullMatrixException
Changed the name of auto-raise configuration from "jm.raise" to "jm.autoraise".
The auto-raise configuration can now be set using system properties with `System.setProperty`. A new method, `getRaiseConfigFromSystemProps()`, has been introduced to safely retrieve the auto-raise configuration from system properties. This method catches `SecurityException` during the retrieval process and logs a warning message instead of throwing the exception.

Additionally, several methods have been refactored to more effectively retrieve the auto-raise configuration from both environment variables and system properties during runtime, especially `getRaiseConfig` and `isAutoRaise`.

NOTE:
If the "jm.autoraise" configuration is set using both environment variables and system properties, the system property will take precedence.
Updated the Javadoc of `JMatrixBaseException` by adding description of new feature of capability to configure the behavior of auto-raised exceptions using either the environment variable or system property by specific name. In addition, this change also improved the existing documentation, including the documentation of `toString` method.
In these huge changes of improving every exceptions in the JMatrix library, we have changed the value of `serialVersionUID` field on every non-deprecated exceptions.

Now the `serialVersionUID` no longer use the calculation provided in changes #60. Instead, now it uses this format:

    430{dd}{MM}{YYYY}{EEE}

Where the {dd} is the date of this project was published to GitHub, {MM} is the month of this project was published to GitHub, {YYYY} is the year of this project was published to GitHub, and the {EEE} is the corresponding error code of the exception (you can check the correct error code for each exceptions in `JMErrorCode` enum).
Refactored the exceptions raiser in `Matrix` class by applying the `JMatrixBaseException.raise` method and replacing the `JMatrixUtils.raiseError` method to raise the exception. The `raise` method was implemented with configurable auto-raise exceptions, this offers control over exception handling and developers can choose the most appropriate error-handling strategy based on their specific needs.

Related refs: c2f2844
@mitsuki31 mitsuki31 self-assigned this Jun 16, 2024
@github-actions github-actions bot added enhancement Enhancing existing features lang:java Some changes on Java code labels Jun 16, 2024
@mitsuki31 mitsuki31 added this to the v1.5.0 milestone Jun 16, 2024
@mitsuki31 mitsuki31 added minor Minor update feature Add new features to improve the project labels Jun 16, 2024
This test suite contains 7 test cases.
@mitsuki31 mitsuki31 merged commit dfcdb16 into master Jun 16, 2024
34 checks passed
@mitsuki31 mitsuki31 deleted the refactor/improve-exceptions-functionality branch June 16, 2024 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancing existing features feature Add new features to improve the project lang:java Some changes on Java code minor Minor update
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

1 participant