A gossip,

A while ago, the blog record was rejected twice because of the name problem, which is enough. Now I have been writing business codes in the company, which makes my algorithm level worse. Recently, I have been learning Rubik’s Cube with a little sister on Youku, and my IQ is not very good. OK, it’s called Retrofit exception handling, but it’s basically a unified exception handling for the network. My previous exception handling was to add a method in BaseActivity or BaseFragment and call that method when there was a problem with the network request. But then I packaged the code I used a lot (including Base) and released AndroidQuick, a repository, so my exception handling couldn’t be handled inside the Base layer, and there were a lot of flaws in the way it was handled.

BaseResponse (Response)

In BaseResponse, determine whether the request has an error (determine the code with the background convention, etc.). If it is not correct, call NetworkError with code

  1. Interface sample

    @FormUrlEncoded
    @POST(Constants.BASE_API + "sendCode")
    Flowable<BaseResponse<SendCodeBean>> getMobileCode(@FieldMap Map<String, String> values);
    Copy the code
  2. BaseResponse

    public class BaseResponse<T> {
    
    	private int code;
    	private String msg;
    	private T res;
    
    	/** * this method has successfully accessed the background, code is the background convention error code, determine whether the access is successful **@paramContext may involve jump Activity * when doing exception handling@returnReturns success or failure */
    	public boolean isOk(Context context) {
    		if (code == 200) {
    			return true;
    		} else {
    			NetworkError.error(context, new ServerException(code, msg));
    			return false; }}// get/set...
    }
    Copy the code

NetworkError (NetworkError)

  • I’m not very good at writing articles. I made detailed comments in the code.

  • code

    public class NetworkError {
    
    	/ * * *@paramContext can be used to jump activities and other operations */
    	public static void error(Context context, Throwable throwable) {
    		RetrofitException.ResponeThrowable responeThrowable = RetrofitException.retrofitException(throwable);
    		// The error code can be determined by the error code to implement the corresponding response
    		switch (responeThrowable.code) {
    			case RetrofitException.ERROR.UNKNOWN:
    			case RetrofitException.ERROR.PARSE_ERROR:
    			case RetrofitException.ERROR.NETWORD_ERROR:
    			case RetrofitException.ERROR.HTTP_ERROR:
    			case RetrofitException.ERROR.SSL_ERROR:
    				Toast.makeText(context, responeThrowable.message, Toast.LENGTH_SHORT).show();
    				break;
    			case -1:
    				// Jump to the login page
    				context.startActivity(new Intent(context, LoginActivity.class));
    				// End all activities except LoginActivity
    				AppManager.finishAllActivity(LoginActivity.class);
    				break;
    			default:
    				Toast.makeText(context, responeThrowable.message, Toast.LENGTH_SHORT).show();
    				break; }}}Copy the code

ServerException ServerException

public class ServerException extends RuntimeException {

    public int code;

    public ServerException(int code, String message) {
        super(message);
        this.code = code; }}Copy the code

RetrofitException RetrofitException

  • This class uses the Instanceof operator to determine the type of exception

  • code

    public class RetrofitException {
    
    	private static final int UNAUTHORIZED = 401;
    	private static final int FORBIDDEN = 403;
    	private static final int NOT_FOUND = 404;
    	private static final int REQUEST_TIMEOUT = 408;
    	private static final int INTERNAL_SERVER_ERROR = 500;
    	private static final int BAD_GATEWAY = 502;
    	private static final int SERVICE_UNAVAILABLE = 503;
    	private static final int GATEWAY_TIMEOUT = 504;
    
    	public static ResponeThrowable retrofitException(Throwable e) {
    		ResponeThrowable ex;
    		if (e instanceof HttpException) {
    			HttpException httpException = (HttpException) e;
    			ex = new ResponeThrowable(e, ERROR.HTTP_ERROR);
    			switch (httpException.code()) {
    				case UNAUTHORIZED:
    				case FORBIDDEN:
    				case NOT_FOUND:
    				case REQUEST_TIMEOUT:
    				case GATEWAY_TIMEOUT:
    				case INTERNAL_SERVER_ERROR:
    				case BAD_GATEWAY:
    				case SERVICE_UNAVAILABLE:
    				default:
    					ex.message = "Network error";
    					break;
    			}
    			return ex;
    		} else if (e instanceof ServerException) {
    			// The server delivered an error
    			ServerException resultException = (ServerException) e;
    			ex = new ResponeThrowable(resultException, resultException.code);
    			ex.message = resultException.getMessage();
    			return ex;
    		} else if (e instanceof JsonParseException
    				|| e instanceof JSONException
    				|| e instanceof ParseException) {
    			ex = new ResponeThrowable(e, ERROR.PARSE_ERROR);
    			ex.message = "Parsing error";
    			return ex;
    		} else if (e instanceof ConnectException
    				|| e instanceof SocketTimeoutException
    				|| e instanceof UnknownHostException) {
    			ex = new ResponeThrowable(e, ERROR.NETWORD_ERROR);
    			ex.message = "Connection failed";
    			return ex;
    		} else if (e instanceof SSLHandshakeException) {
    			ex = new ResponeThrowable(e, ERROR.SSL_ERROR);
    			ex.message = "Certificate verification failed";
    			return ex;
    		} else {
    			ex = new ResponeThrowable(e, ERROR.UNKNOWN);
    			ex.message = "Unknown error";
    			returnex; }}/** * the convention is abnormal */
    	class ERROR {
    		/** * Unknown error */
    		public static final int UNKNOWN = 1000;
    		/** * parsing error */
    		public static final int PARSE_ERROR = 1001;
    		/** * Network error */
    		public static final int NETWORD_ERROR = 1002;
    		/** * protocol error */
    		public static final int HTTP_ERROR = 1003;
    		/** * Certificate error */
    		public static final int SSL_ERROR = 1005;
    	}
    
    	public static class ResponeThrowable extends Exception {
    		public int code;
    		public String message;
    
    		public ResponeThrowable(Throwable throwable, int code) {
    			super(throwable);
    			this.code = code; }}}Copy the code

Six, the way of use

Map<String, String> map = new LinkedHashMap<>();
map.put("id", mId);
map.put("uid", SPUtils.getInstance().getString("uid"));
RetrofitClient
		// singleton call
		.getInstance()
		// Get the request interface
		.gService
		// Call the interface method
		.getMobileCode(map)
		// Switch threads with compose
		.compose(RxUtil.rxSchedulerHelper())
		/ / subscribe
		.subscribe(response -> {
			if (response.isOk(mContext)) {
				// All correct
			} else {
				// Error sent by the server (BaseResponse isOk() calls exception handling)
			}
		}, throwable -> {
			LogUtils.e(throwable);
			/ / Retrofit anomalies
			NetworkError.error(context, throwable);
		});
Copy the code

Seven, the source code

https://github.com/sdwfqin/AndroidQuick

Welcome to provide your valuable comments and suggestions, E-mail: [email protected]