Created
July 4, 2022 08:01
-
-
Save arafaysaleem/da0d28ebedf54621c56c2edee83c73cc to your computer and use it in GitHub Desktop.
Logging Interceptor For Network Layer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:io'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:dio/dio.dart'; | |
//helpers | |
import '../../../helpers/typedefs.dart'; | |
/// A class that intercepts network requests for logging purposes only. This is | |
/// the second interceptor in case of both request and response. | |
/// | |
/// ** This interceptor doesn't modify the request or response in any way. And | |
/// only works in `debug` mode ** | |
class LoggingInterceptor extends Interceptor { | |
/// This method intercepts an out-going request before it reaches the | |
/// destination. | |
/// | |
/// [options] contains http request information and configuration. | |
/// [handler] is used to forward, resolve, or reject requests. | |
/// | |
/// This method is used to log details of all out going requests, then pass | |
/// it on after that. It may again be intercepted if there are any | |
/// after it. If none, it is passed to [Dio]. | |
/// | |
/// The [RequestInterceptorHandler] in each method controls the what will | |
/// happen to the intercepted request. It has 3 possible options: | |
/// | |
/// - [handler.next]/[super.onRequest], if you want to forward the request. | |
/// - [handler.resolve]/[super.onResponse], if you want to resolve the | |
/// request with your custom [Response]. All ** request ** interceptors are ignored. | |
/// - [handler.reject]/[super.onError], if you want to fail the request | |
/// with your custom [DioError]. | |
@override | |
void onRequest( | |
RequestOptions options, | |
RequestInterceptorHandler handler, | |
) { | |
final httpMethod = options.method.toUpperCase(); | |
final url = options.baseUrl + options.path; | |
debugPrint('--> $httpMethod $url'); //GET www.example.com/mock_path/all | |
debugPrint('\tHeaders:'); | |
options.headers.forEach((k, Object? v) => debugPrint('\t\t$k: $v')); | |
if (options.queryParameters.isNotEmpty) { | |
debugPrint('\tqueryParams:'); | |
options.queryParameters | |
.forEach((k, Object? v) => debugPrint('\t\t$k: $v')); | |
} | |
if (options.data != null) { | |
debugPrint('\tBody: ${options.data}'); | |
} | |
debugPrint('--> END $httpMethod'); | |
return super.onRequest(options, handler); | |
} | |
/// This method intercepts an incoming response before it reaches Dio. | |
/// | |
/// [response] contains http [Response] info. | |
/// [handler] is used to forward, resolve, or reject responses. | |
/// | |
/// This method is used to log all details of incoming responses, then pass | |
/// it on after that. It may again be intercepted if there are any | |
/// after it. If none, it is passed to [Dio]. | |
/// | |
/// The [RequestInterceptorHandler] in each method controls the what will | |
/// happen to the intercepted response. It has 3 possible options: | |
/// | |
/// - [handler.next]/[super.onRequest], if you want to forward the [Response]. | |
/// - [handler.resolve]/[super.onResponse], if you want to resolve the | |
/// [Response] with your custom data. All ** response ** interceptors are ignored. | |
/// - [handler.reject]/[super.onError], if you want to fail the response | |
/// with your custom [DioError]. | |
@override | |
void onResponse( | |
Response response, | |
ResponseInterceptorHandler handler, | |
) { | |
debugPrint('<-- RESPONSE'); | |
debugPrint('\tStatus code: ${response.statusCode}'); | |
if (response.statusCode == 304) { | |
debugPrint('\tSource: Cache'); | |
} else { | |
debugPrint('\tSource: Network'); | |
} | |
debugPrint('\tResponse: ${response.data}'); | |
debugPrint('<-- END HTTP'); | |
return super.onResponse(response, handler); | |
} | |
/// This method intercepts any exceptions thrown by Dio, or passed from a | |
/// previous interceptor. | |
/// | |
/// [dioError] contains error info when the request failed. | |
/// [handler] is used to forward, resolve, or reject errors. | |
/// | |
/// This method is used to log all details of the error arising due to the | |
/// failed request, then pass it on after that. It may again be intercepted | |
/// if there are any after it. If none, it is passed to [Dio]. | |
/// | |
/// ** The structure of response in case of errors is dependant on the API and | |
/// may not always be the same. It might need changing according to your | |
/// own API. ** | |
/// | |
/// The [RequestInterceptorHandler] in each method controls the what will | |
/// happen to the intercepted error. It has 3 possible options: | |
/// | |
/// - [handler.next]/[super.onRequest], if you want to forward the [Response]. | |
/// - [handler.resolve]/[super.onResponse], if you want to resolve the | |
/// [Response] with your custom data. All ** error ** interceptors are ignored. | |
/// - [handler.reject]/[super.onError], if you want to fail the response | |
/// with your custom [DioError]. | |
@override | |
void onError( | |
DioError dioError, | |
ErrorInterceptorHandler handler, | |
) { | |
debugPrint('--> ERROR'); | |
final httpMethod = dioError.requestOptions.method.toUpperCase(); | |
final url = dioError.requestOptions.baseUrl + dioError.requestOptions.path; | |
debugPrint('\tMETHOD: $httpMethod'); // GET | |
debugPrint('\tURL: $url'); // URL | |
if (dioError.response != null) { | |
debugPrint('\tStatus code: ${dioError.response!.statusCode}'); | |
if (dioError.response!.data != null) { | |
final headers = | |
dioError.response!.data['headers'] as JSON; //API Dependant | |
final message = headers['message'] as String; //API Dependant | |
final code = headers['code'] as String; //API Dependant | |
debugPrint('\tException: $code'); | |
debugPrint('\tMessage: $message'); | |
if (headers.containsKey('data')) { | |
//API Dependant | |
final data = headers['data'] as List<Object?>; | |
if (data.isNotEmpty) { | |
debugPrint('\tData: $data'); | |
} | |
} | |
} else { | |
debugPrint('${dioError.response!.data}'); | |
} | |
} else if (dioError.error is SocketException) { | |
const message = 'No internet connectivity'; | |
debugPrint('\tException: FetchDataException'); | |
debugPrint('\tMessage: $message'); | |
} else { | |
debugPrint('\tUnknown Error'); | |
} | |
debugPrint('<-- END ERROR'); | |
return super.onError(dioError, handler); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment