Skip to content

Commit

Permalink
refactor exception handler
Browse files Browse the repository at this point in the history
  • Loading branch information
fulan.zjf committed Jan 8, 2019
1 parent 194efe8 commit 5ac3bc3
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.alibaba.cola.command.CommandHub;
import com.alibaba.cola.command.CommandInterceptorI;
import com.alibaba.cola.command.CommandInvocation;
import com.alibaba.cola.common.ApplicationContextHelper;
import com.alibaba.cola.common.ColaConstant;
import com.alibaba.cola.dto.Command;
import com.alibaba.cola.exception.ColaException;
Expand All @@ -29,20 +30,17 @@
* @author fulan.zjf 2017-11-04
*/

@SuppressWarnings({ "rawtypes", "unchecked" })
@Component
public class CommandRegister implements RegisterI, ApplicationContextAware {
public class CommandRegister implements RegisterI {

@Autowired
private CommandHub commandHub;

private ApplicationContext applicationContext;

@Override
public void doRegistration(Class<?> targetClz) {
Class<? extends Command> commandClz = getCommandFromExecutor(targetClz);
CommandInvocation commandInvocation = new CommandInvocation();
commandInvocation.setCommandExecutor((CommandExecutorI) applicationContext.getBean(targetClz));
CommandInvocation commandInvocation = ApplicationContextHelper.getBean(CommandInvocation.class);
commandInvocation.setCommandExecutor((CommandExecutorI) ApplicationContextHelper.getBean(targetClz));
commandInvocation.setPreInterceptors(collectInterceptors(commandClz, true));
commandInvocation.setPostInterceptors(collectInterceptors(commandClz, false));
commandHub.getCommandRepository().put(commandClz, commandInvocation);
Expand Down Expand Up @@ -95,8 +93,4 @@ private Iterable<CommandInterceptorI> collectInterceptors(Class<? extends Comman
return commandItr;
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
package com.alibaba.cola.command;

import com.alibaba.cola.common.ApplicationContextHelper;
import com.alibaba.cola.exception.*;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.alibaba.cola.dto.Command;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.logger.Logger;
import com.alibaba.cola.logger.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Just send Command to CommandBus,
*
Expand All @@ -21,87 +12,12 @@
@Component
public class CommandBus implements CommandBusI{

Logger logger = LoggerFactory.getLogger(CommandBus.class);

@Autowired
private CommandHub commandHub;


@Override
public Response send(Command cmd) {
Response response = null;
try {
response = commandHub.getCommandInvocation(cmd.getClass()).invoke(cmd);
}
catch (Exception exception) {
response = handleException(cmd, exception);
}
return response;
}

private Response handleException(Command cmd, Exception exception) {
Response response = getResponseInstance(cmd);

ExceptionHandlerI exceptionHandler = getCustomerizedExceptionHandler();
if (exceptionHandler != null){
exceptionHandler.handleException(cmd, response, exception);
return response;
}

defaultHandleException(cmd, response, exception);
return response;
}

private Response getResponseInstance(Command cmd) {
Class responseClz = commandHub.getResponseRepository().get(cmd.getClass());
try {
return (Response) responseClz.newInstance();
} catch (Exception e) {
throw new ColaException(e.getMessage());
}
}

private void defaultHandleException(Command cmd, Response response, Exception exception) {
formResponse(response, exception);

printLog(cmd, response, exception);
}

private void printLog(Command cmd, Response response, Exception exception) {
if(exception instanceof BizException || exception instanceof ParamException){
//biz exception is expected, only warn it
logger.warn(buildErrorMsg(cmd, response));
}
else{
//sys exception should be monitored, and pay attention to it
logger.error(buildErrorMsg(cmd, response), exception);
}
}

private String buildErrorMsg(Command cmd, Response response) {
return "Process [" + cmd + "] failed, errorCode: "
+ response.getErrCode() + " errorMsg:"
+ response.getErrMessage();
}

private void formResponse(Response response, Exception exception) {
if (exception instanceof AppException) {
ErrorCodeI errCode = ((AppException) exception).getErrCode();
response.setErrCode(errCode.getErrCode());
}
else {
response.setErrCode(BasicErrorCode.S_UNKNOWN.getErrCode());
}
response.setErrMessage(exception.getMessage());
}

private ExceptionHandlerI getCustomerizedExceptionHandler() {
try {
return ApplicationContextHelper.getBean(ExceptionHandlerI.class);
}
catch (NoSuchBeanDefinitionException ex){
return null;
}
return commandHub.getCommandInvocation(cmd.getClass()).invoke(cmd);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,90 @@

import com.alibaba.cola.dto.Command;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.exception.ColaException;
import com.alibaba.cola.exception.DefaultExceptionHandler;
import com.alibaba.cola.exception.ExceptionHandlerFactory;
import com.alibaba.cola.exception.ExceptionHandlerI;
import com.alibaba.cola.logger.Logger;
import com.alibaba.cola.logger.LoggerFactory;
import com.google.common.collect.FluentIterable;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;

public class CommandInvocation<R extends Response, C extends Command> {

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class CommandInvocation{

private static Logger logger = LoggerFactory.getLogger(CommandInvocation.class);

@Setter
private CommandExecutorI<R,C> commandExecutor;
private CommandExecutorI commandExecutor;
@Setter
private Iterable<CommandInterceptorI> preInterceptors;
@Setter
private Iterable<CommandInterceptorI> postInterceptors;


@Autowired
private CommandHub commandHub;


public CommandInvocation() {

}

public CommandInvocation(CommandExecutorI<R, C> commandExecutor, List<CommandInterceptorI> preInterceptors,
public CommandInvocation(CommandExecutorI commandExecutor, List<CommandInterceptorI> preInterceptors,
List<CommandInterceptorI> postInterceptors){
this.commandExecutor = commandExecutor;
this.preInterceptors = preInterceptors;
this.postInterceptors = postInterceptors;
}

public R invoke(C command) {
preIntercept(command);
R response = null;
public Response invoke(Command command) {
Response response = null;
try {
preIntercept(command);
response = commandExecutor.execute(command);
response.setSuccess(true);
}
catch(Exception e){
response = getResponseInstance(command);
response.setSuccess(false);
ExceptionHandlerFactory.getExceptionHandler().handleException(command, response, e);
}
finally {
//make sure post interceptors performs even though exception happens
postIntercept(command, response);
postIntercept(command, response);
}
return response;
}

private void postIntercept(C command, R response) {
for (CommandInterceptorI postInterceptor : FluentIterable.from(postInterceptors).toSet()) {
postInterceptor.postIntercept(command, response);
private void postIntercept(Command command, Response response) {
try {
for (CommandInterceptorI postInterceptor : FluentIterable.from(postInterceptors).toSet()) {
postInterceptor.postIntercept(command, response);
}
}
catch(Exception e){
logger.error("postInterceptor error:"+e.getMessage(), e);
}
}

private void preIntercept(C command) {
private void preIntercept(Command command) {
for (CommandInterceptorI preInterceptor : FluentIterable.from(preInterceptors).toSet()) {
preInterceptor.preIntercept(command);
}
}

private Response getResponseInstance(Command cmd) {
Class responseClz = commandHub.getResponseRepository().get(cmd.getClass());
try {
return (Response) responseClz.newInstance();
} catch (Exception e) {
return new Response();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.alibaba.cola.exception;

import com.alibaba.cola.dto.Command;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.logger.Logger;
import com.alibaba.cola.logger.LoggerFactory;

/**
* DefaultExceptionHandler
*
* @author Frank Zhang
* @date 2019-01-08 9:51 AM
*/
public class DefaultExceptionHandler implements ExceptionHandlerI{

private Logger logger = LoggerFactory.getLogger(DefaultExceptionHandler.class);

public static DefaultExceptionHandler singleton = new DefaultExceptionHandler();

@Override
public void handleException(Command cmd, Response response, Exception exception) {
buildResponse(response, exception);
printLog(cmd, response, exception);
}

private void printLog(Command cmd, Response response, Exception exception) {
if(exception instanceof BizException || exception instanceof ParamException){
//biz exception is expected, only warn it
logger.warn(buildErrorMsg(cmd, response));
}
else{
//sys exception should be monitored, and pay attention to it
logger.error(buildErrorMsg(cmd, response), exception);
}
}

private String buildErrorMsg(Command cmd, Response response) {
return "Process [" + cmd + "] failed, errorCode: "
+ response.getErrCode() + " errorMsg:"
+ response.getErrMessage();
}

private void buildResponse(Response response, Exception exception) {
if (exception instanceof AppException) {
ErrorCodeI errCode = ((AppException) exception).getErrCode();
response.setErrCode(errCode.getErrCode());
}
else {
response.setErrCode(BasicErrorCode.S_UNKNOWN.getErrCode());
}
response.setErrMessage(exception.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.alibaba.cola.exception;

import com.alibaba.cola.common.ApplicationContextHelper;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

/**
* ExceptionHandlerFactory
*
* @author Frank Zhang
* @date 2019-01-08 9:51 AM
*/
public class ExceptionHandlerFactory {

public static ExceptionHandlerI getExceptionHandler(){
try {
return ApplicationContextHelper.getBean(ExceptionHandlerI.class);
}
catch (NoSuchBeanDefinitionException ex){
return DefaultExceptionHandler.singleton;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import com.alibaba.cola.test.customer.validator.extensionpoint.AddCustomerValidatorExtPt;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.function.Function;

/**
* AddCustomerCmdExe
*
Expand Down
6 changes: 0 additions & 6 deletions cola-framework/pom.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>com.taobao</groupId>
<artifactId>parent</artifactId>
<version>2.0.0</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba.cola</groupId>
<artifactId>all</artifactId>
Expand Down

0 comments on commit 5ac3bc3

Please sign in to comment.