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

#338 Error code parsing supports custom parsers. #339

Merged
merged 1 commit into from
Sep 3, 2022

Conversation

ddphin
Copy link

@ddphin ddphin commented Sep 3, 2022

#338 Error code parsing supports custom parsers.

The original configuration method is as follows:

{
  "errorCodeDictionaries": [
      {
        "title": "title",
        "enumClassName": "com.power.common.enums.HttpCodeEnum", // Error code enumeration class
        "codeField": "code", // Field name for the error code's code
        "descField": "message" // Field name for the error code's description
      }}
}

A new custom parser configuration parameter valuesResolverClass has been added, as follows:

{
  "errorCodeDictionaries": [
      {
          "title": "title",
          "enumClassName": "com.power.common.notenums.EException", // Error code class (not an Enum)
          "valuesResolverClass": "com.power.common.notenums.EExceptionValuesResolver", // Error code resolution class
      }}
}

Smart-doc provides an interface DictionaryValuesResolver, as follows:

public interface DictionaryValuesResolver {
    <T extends EnumDictionary> Collection<T> resolve();
}

The newly added valuesResolverClass parameter corresponds to a class that implements the DictionaryValuesResolver interface. Its functionality in the EExceptionValuesResolver class is as follows:

public class EExceptionValuesResolver implements DictionaryValuesResolver {
    @Override
    public <T extends EnumDictionary> Collection<T> resolve() {
        List<EnumDictionary> list = new ArrayList<>();
        // Technical processing
        return list;
    }
}

Smart-doc extension. In the com.power.doc.utils.DocUtil#errorCodeDictToList method, add handling for the valuesResolverClass parameter. The original key code position is as follows:

if (clzz.isInterface()) {
    Set<Class<? extends Enum>> enumImplementSet = dictionary.getEnumImplementSet();
    if (CollectionUtil.isEmpty(enumImplementSet)) {
        continue;
    }

    for (Class<? extends Enum> enumClass : enumImplementSet) {
        JavaClass interfaceClass = javaProjectBuilder.getClassByName(enumClass.getCanonicalName());
        if (Objects.nonNull(interfaceClass.getTagByName(DocTags.IGNORE))) {
            continue;
        }
        List<ApiErrorCode> enumDictionaryList = EnumUtil.getEnumInformation(enumClass, dictionary.getCodeField(),
                dictionary.getDescField());
        errorCodeList.addAll(enumDictionaryList);
    }

} else {
    JavaClass javaClass = javaProjectBuilder.getClassByName(clzz.getCanonicalName());
    if (Objects.nonNull(javaClass.getTagByName(DocTags.IGNORE))) {
        continue;
    }
    List<ApiErrorCode> enumDictionaryList = EnumUtil.getEnumInformation(clzz, dictionary.getCodeField(),
            dictionary.getDescField());
    errorCodeList.addAll(enumDictionaryList);
}

At the beginning, add an extension branch and modify it as follows:

Class<?> valuesResolverClass = null;
if (StringUtil.isNotEmpty(dictionary.getValuesResolverClass())) {
    valuesResolverClass = classLoader.loadClass(dictionary.getValuesResolverClass());
}
if (null != valuesResolverClass && SmartValuesResolver.class.isAssignableFrom(valuesResolverClass)) {
    List<ApiErrorCode> enumDictionaryList = valuesResolverClass.getConstructor().newInstance().resolve();
    errorCodeList.addAll(enumDictionaryList);
}
else if (clzz.isInterface()) {
    // Original code

} else {
    // Original code
}

Motivation(提出这个pr目的)

Company A has unified coding standards, and all exceptions (including error codes) inherit from an abstract base class (parent class) EException (neither an interface nor an enum).

@Getter
public class EException {
    private final int code; // Unique within the inheritance system, throwing an exception if constraints are violated upon initialization
    private final String name; // Unique within the inheritance system, throwing an exception if constraints are violated upon initialization
    private String description;
    private String solution;
    // Some technical processing, this class cannot be instantiated with new, allowing it to be inherited and only created through the following of method

    protected static EException of(String name, int code, String description, String solution) {
      // Technical processing
    }
    public static EException valueOf(int code) {
      // Technical processing
    }
    public static EException valueOf(String name) {
      // Technical processing
    }
    public static Set<EException> values() {
      // Technical processing, this method returns all defined exceptions (including parents and all subclasses (as long as the ancestor is this class, its defined exceptions will be returned))
    }
}

Basic common exception definition (inheriting EException)

@NoArgsConstructor(access = AccessLevel.PROTECTED) // Can continue to be inherited
public class BaseEException extend EException {
    public static final EException BAD_REQUEST = of("BAD_REQUEST", 400000, "Request syntax error: {0}", "Syntax format: {1}");
    public static final EException UNAUTHORIZED = of("UNAUTHORIZED", 401000, "Request requires user authentication", "Please log in first");
    public static final EException SYSTEM_ERROR = of("SYSTEM_ERROR", 500000, "System exception:{0}", "Please try again later or contact the administrator");
    // etc.
}

Microservice custom exception definition (inheriting BaseEException)

@NoArgsConstructor(access = AccessLevel.PRIVATE) // Cannot continue to be inherited
public class BizEException extend BaseEException {
    public static final EException PARAM_NAME_EXIST = of("PARAM_NAME_EXIST", 400100, "Parameter name already exists!", "Please use another name or contact the administrator");
    // etc.
}

Through subclasses, all definitions of static exceptions in the inheritance relationship can be referenced, and traditionally, the way enums implement interfaces independently and do not interoperate, preventing global maintenance across applications. This technique also enables the aggregation of all exceptions within a microservice through the BizEException, facilitating global maintenance.

@shalousun shalousun merged commit 8c65ce9 into TongchengOpenSource:master Sep 3, 2022
@shalousun shalousun changed the title #338 错误码解析支持自定义解析器 #338 Error code parsing supports custom parsers. Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants