aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGusted <williamzijl7@hotmail.com>2021-12-28 13:28:27 +0000
committerGitHub <noreply@github.com>2021-12-28 21:28:27 +0800
commite4e3df6c66dbeac6ac5bceff8ac4f05dbea30d70 (patch)
treeea7ef42f8d34580b8ec1319f6bc2cd84c6fb973a
parentd2fac636d16a596a36a3088ff05ffe812ba6eff2 (diff)
downloadgitea-e4e3df6c66dbeac6ac5bceff8ac4f05dbea30d70.tar.gz
gitea-e4e3df6c66dbeac6ac5bceff8ac4f05dbea30d70.zip
Handle invalid issues (#18111)
* Handle invalid issues - When you hover over a issue reference, and the issue doesn't exist, it will just hang on the loading animation. - This patch fixes that by showing them the pop-up with a "Error occured" message. * Add I18N * refactor * fix comment for lint * fix unit test for i18n * fix unit test for i18n * add comments Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
-rw-r--r--integrations/api_releases_test.go2
-rw-r--r--integrations/repo_branch_test.go2
-rw-r--r--modules/context/api.go23
-rw-r--r--options/locale/locale_en-US.ini8
-rw-r--r--templates/base/head.tmpl5
-rw-r--r--web_src/js/components/ContextPopup.vue28
6 files changed, 45 insertions, 23 deletions
diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go
index b3d9c898e4..815b749110 100644
--- a/integrations/api_releases_test.go
+++ b/integrations/api_releases_test.go
@@ -207,7 +207,7 @@ func TestAPIGetReleaseByTag(t *testing.T) {
var err *api.APIError
DecodeJSON(t, resp, &err)
- assert.EqualValues(t, "Not Found", err.Message)
+ assert.NotEmpty(t, err.Message)
}
func TestAPIDeleteReleaseByTagName(t *testing.T) {
diff --git a/integrations/repo_branch_test.go b/integrations/repo_branch_test.go
index af5c475ea7..aef28515e7 100644
--- a/integrations/repo_branch_test.go
+++ b/integrations/repo_branch_test.go
@@ -141,7 +141,7 @@ func TestCreateBranchInvalidCSRF(t *testing.T) {
resp = session.MakeRequest(t, NewRequest(t, "GET", loc), http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Equal(t,
- "Bad Request: Invalid CSRF token",
+ "Bad Request: invalid CSRF token",
strings.TrimSpace(htmlDoc.doc.Find(".ui.message").Text()),
)
}
diff --git a/modules/context/api.go b/modules/context/api.go
index 574d7c4248..635a54c7ef 100644
--- a/modules/context/api.go
+++ b/modules/context/api.go
@@ -30,6 +30,11 @@ type APIContext struct {
Org *APIOrganization
}
+// Currently, we have the following common fields in error response:
+// * message: the message for end users (it shouldn't be used for error type detection)
+// if we need to indicate some errors, we should introduce some new fields like ErrorCode or ErrorType
+// * url: the swagger document URL
+
// APIError is error format response
// swagger:response error
type APIError struct {
@@ -47,8 +52,8 @@ type APIValidationError struct {
// APIInvalidTopicsError is error format response to invalid topics
// swagger:response invalidTopicsError
type APIInvalidTopicsError struct {
- Topics []string `json:"invalidTopics"`
- Message string `json:"message"`
+ Message string `json:"message"`
+ InvalidTopics []string `json:"invalidTopics"`
}
//APIEmpty is an empty response
@@ -122,9 +127,9 @@ func (ctx *APIContext) InternalServerError(err error) {
})
}
-var (
- apiContextKey interface{} = "default_api_context"
-)
+type apiContextKeyType struct{}
+
+var apiContextKey = apiContextKeyType{}
// WithAPIContext set up api context in request
func WithAPIContext(req *http.Request, ctx *APIContext) *http.Request {
@@ -351,7 +356,7 @@ func ReferencesGitRepo(allowEmpty bool) func(http.Handler) http.Handler {
// NotFound handles 404s for APIContext
// String will replace message, errors will be added to a slice
func (ctx *APIContext) NotFound(objs ...interface{}) {
- var message = "Not Found"
+ var message = ctx.Tr("error.not_found")
var errors []string
for _, obj := range objs {
// Ignore nil
@@ -367,9 +372,9 @@ func (ctx *APIContext) NotFound(objs ...interface{}) {
}
ctx.JSON(http.StatusNotFound, map[string]interface{}{
- "message": message,
- "documentation_url": setting.API.SwaggerURL,
- "errors": errors,
+ "message": message,
+ "url": setting.API.SwaggerURL,
+ "errors": errors,
})
}
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 5248f98069..9164d5ffdc 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -104,10 +104,12 @@ error404 = The page you are trying to reach either <strong>does not exist</stron
never = Never
[error]
-occurred = An error has occurred
-report_message = If you are sure this is a Gitea bug, please search for issue on <a href="https://github.com/go-gitea/gitea/issues">GitHub</a> and open new issue if necessary.
+occurred = An error occurred
+report_message = If you are sure this is a Gitea bug, please search for issues on <a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a> or open a new issue if necessary.
missing_csrf = Bad Request: no CSRF token present
-invalid_csrf = Bad Request: Invalid CSRF token
+invalid_csrf = Bad Request: invalid CSRF token
+not_found = The target couldn't be found.
+network_error = Network error
[startpage]
app_desc = A painless, self-hosted Git service
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index e9c2d512df..8bc6ae689d 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -46,10 +46,13 @@
]).values()),
{{end}}
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
+ {{/* this global i18n object should only contain gereral texts. for specalized texts, it should be provied inside the related modules by: (1) API response (2) HTML data-attribute (3) PageData */}}
i18n: {
copy_success: '{{.i18n.Tr "copy_success"}}',
copy_error: '{{.i18n.Tr "copy_error"}}',
- }
+ error_occurred: '{{.i18n.Tr "error.occurred"}}',
+ network_error: '{{.i18n.Tr "error.network_error"}}',
+ },
};
{{/* in case some pages don't render the pageData, we make sure it is an object to prevent null access */}}
window.config.pageData = window.config.pageData || {};
diff --git a/web_src/js/components/ContextPopup.vue b/web_src/js/components/ContextPopup.vue
index efaa7be89e..c002a3d066 100644
--- a/web_src/js/components/ContextPopup.vue
+++ b/web_src/js/components/ContextPopup.vue
@@ -16,13 +16,17 @@
</div>
</div>
</div>
+ <div v-if="!loading && issue === null">
+ <p><small>{{ i18nErrorOccurred }}</small></p>
+ <p>{{ i18nErrorMessage }}</p>
+ </div>
</div>
</template>
<script>
import {SvgIcon} from '../svg.js';
-const {appSubUrl} = window.config;
+const {appSubUrl, i18n} = window.config;
// NOTE: see models/issue_label.go for similar implementation
const srgbToLinear = (color) => {
@@ -49,7 +53,9 @@ export default {
data: () => ({
loading: false,
- issue: null
+ issue: null,
+ i18nErrorOccurred: i18n.error_occurred,
+ i18nErrorMessage: null,
}),
computed: {
@@ -112,14 +118,20 @@ export default {
methods: {
load(data, callback) {
this.loading = true;
- $.get(`${appSubUrl}/api/v1/repos/${data.owner}/${data.repo}/issues/${data.index}`, (issue) => {
+ this.i18nErrorMessage = null;
+ $.get(`${appSubUrl}/api/v1/repos/${data.owner}/${data.repo}/issues/${data.index}`).done((issue) => {
this.issue = issue;
+ }).fail((jqXHR) => {
+ if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
+ this.i18nErrorMessage = jqXHR.responseJSON.message;
+ } else {
+ this.i18nErrorMessage = i18n.network_error;
+ }
+ }).always(() => {
this.loading = false;
- this.$nextTick(() => {
- if (callback) {
- callback();
- }
- });
+ if (callback) {
+ this.$nextTick(callback);
+ }
});
}
}