@@ -75,30 +75,43 @@ func (v SystemComplexError) Error() string {
7575 return fmt .Sprintf ("%v, %v" , v .Code .Error (), v .Message )
7676}
7777
78+ // application level, with code.
79+ type AppError interface {
80+ Code () int
81+ error
82+ }
83+
7884// http standard error response.
7985// @remark for not SystemError, we will use logger.E to print it.
8086// @remark user can use WriteError() for simple api.
8187func Error (ctx ol.Context , err error ) http.Handler {
8288 // for complex error, use code instead.
8389 if v , ok := err .(SystemComplexError ); ok {
8490 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
85- ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , err )
86- jsonHandler (ctx , v ).ServeHTTP (w , r )
91+ jsonHandler (ctx , FilterCplxSystemError (ctx , w , r , v )).ServeHTTP (w , r )
8792 })
8893 }
8994
9095 // for int error, use code instead.
9196 if v , ok := err .(SystemError ); ok {
92- return jsonHandler (ctx , map [string ]int {"code" : int (v )})
97+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
98+ jsonHandler (ctx , FilterSystemError (ctx , w , r , v )).ServeHTTP (w , r )
99+ })
93100 }
94101
102+ // for application error, use code instead.
103+ if v , ok := err .(AppError ); ok {
104+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
105+ jsonHandler (ctx , FilterAppError (ctx , w , r , v )).ServeHTTP (w , r )
106+ })
107+ }
108+
109+ // unknown error, log and response detail
95110 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
96111 SetHeader (w )
97112 w .Header ().Set ("Content-Type" , HttpJson )
98113
99- // unknown error, log and response detail
100- http .Error (w , err .Error (), http .StatusInternalServerError )
101- ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , err )
114+ http .Error (w , FilterError (ctx , w , r , err ), http .StatusInternalServerError )
102115 })
103116}
104117
@@ -112,19 +125,9 @@ func CplxError(ctx ol.Context, code SystemError, message string) http.Handler {
112125// @remark user can use nil v to response success, which data is null.
113126// @remark user can use WriteData() for simple api.
114127func Data (ctx ol.Context , v interface {}) http.Handler {
115- rv := map [string ]interface {}{
116- "code" : 0 ,
117- "server" : os .Getpid (),
118- "data" : v ,
119- }
120-
121- // for string, directly use it without convert,
122- // for the type covert by golang maybe modify the content.
123- if v , ok := v .(string ); ok {
124- rv ["data" ] = v
125- }
126-
127- return jsonHandler (ctx , rv )
128+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
129+ jsonHandler (ctx , FilterData (ctx , w , r , v )).ServeHTTP (w , r )
130+ })
128131}
129132
130133// set http header, for directly use the w,
@@ -211,3 +214,37 @@ func WriteError(ctx ol.Context, w http.ResponseWriter, r *http.Request, err erro
211214func WriteCplxError (ctx ol.Context , w http.ResponseWriter , r * http.Request , code SystemError , message string ) {
212215 CplxError (ctx , code , message ).ServeHTTP (w , r )
213216}
217+
218+ // for hijack to define the response structure.
219+ // user can redefine these functions for special response.
220+ var FilterCplxSystemError = func (ctx ol.Context , w http.ResponseWriter , r * http.Request , o SystemComplexError ) interface {} {
221+ ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , o )
222+ return o
223+ }
224+ var FilterSystemError = func (ctx ol.Context , w http.ResponseWriter , r * http.Request , o SystemError ) interface {} {
225+ ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , o )
226+ return map [string ]int {"code" : int (o )}
227+ }
228+ var FilterAppError = func (ctx ol.Context , w http.ResponseWriter , r * http.Request , err AppError ) interface {} {
229+ ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , err )
230+ return map [string ]interface {}{"code" : err .Code (), "data" : err .Error ()}
231+ }
232+ var FilterError = func (ctx ol.Context , w http.ResponseWriter , r * http.Request , err error ) string {
233+ ol .Ef (ctx , "Serve %v failed, err is %+v" , r .URL , err )
234+ return err .Error ()
235+ }
236+ var FilterData = func (ctx ol.Context , w http.ResponseWriter , r * http.Request , o interface {}) interface {} {
237+ rv := map [string ]interface {}{
238+ "code" : 0 ,
239+ "server" : os .Getpid (),
240+ "data" : o ,
241+ }
242+
243+ // for string, directly use it without convert,
244+ // for the type covert by golang maybe modify the content.
245+ if v , ok := o .(string ); ok {
246+ rv ["data" ] = v
247+ }
248+
249+ return rv
250+ }
0 commit comments