[Refactor][Plugin API] Dispart devlake's backend error and expections
What and why to refactor
What are you trying to refactor? Why should it be refactored now?
Recently I sumbit PR #6071 , it's caused by mismatched field's type from plugin zentao's remote API response. Usually, all known errors in the server side can be wrapped to an error message to the client side, only unknown errors/expections can cause server api return http status code 500.
Our current code will return http status code 500 because if plugin returns an error with nil body here https://github.com/apache/incubator-devlake/blob/main/backend/server/api/router.go#L135.
We have an similar issue #6038, and there will be more problems in foreseeable future. and it's a unreasonable design. So refactor is necessary.
Describe the solution you'd like
How to refactor?
- Frontend Support api body struct for all plugin related APIs.
type TypedApiBody[T any] struct {
Success bool `json:"success"`
Message string `json:"message"`
Causes []string `json:"causes"`
Data T `json:"data"`
}
- Backend
- In plugins' API, if some errors occur, handle errors like this:
func PluginAPI(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
err := doSth()
if err != nil {
log.Error(err, "some additional info") // log it, necessary!!!
return TypedApiBody{
Success: False,
Message: "some useful error message",
Causes: []string{"reason A", "reason B"}
}, nil
}
return respBody, nil
}
- In plugin handler's caller, wrap handler then recover it.
callHandler := func(input *ApiResourceInput) (output *ApiResourceOutput, err errors.Error){
defer func(){
if recoverErr := recover(); recoverErr != nil {
log.Error(err, "some additional info")
err = recoverErr
}
}
ouput, err = handler(input)
}
output, err := callHandler(input)
if err != nil {
if output != nil && output.Body != nil {
logruslog.Global.Error(err, "")
shared.ApiOutputSuccess(c, output.Body, err.GetType().GetHttpCode())
} else {
shared.ApiOutputError(c, err)
}
}
Related issues
#6038 #6071
Additional context
Add any other context or screenshots about the feature request here.
This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.
This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.
This issue has been automatically marked as stale because it has been inactive for 60 days. It will be closed in next 7 days if no further activity occurs.
This issue has been closed because it has been inactive for a long time. You can reopen it if you encounter the similar problem in the future.