Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitedff802

Browse files
committed
Show report error modal for RPC errors
1 parent9785cd0 commitedff802

File tree

7 files changed

+102
-50
lines changed

7 files changed

+102
-50
lines changed

‎backend/main/views.py‎

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
importinspect
21
importjson
32
importlogging
3+
importtraceback
44
fromdatetimeimportdatetime
55
fromioimportStringIO
66
frompathlibimportPath
@@ -15,7 +15,7 @@
1515
fromdjango.contrib.auth.mixinsimportLoginRequiredMixin
1616
fromdjango.contrib.messages.viewsimportSuccessMessageMixin
1717
fromdjango.formsimportModelForm
18-
fromdjango.httpimportJsonResponse,HttpResponseBadRequest,HttpResponse
18+
fromdjango.httpimportJsonResponse,HttpResponse
1919
fromdjango.viewsimportView
2020
fromdjango.views.genericimportCreateView
2121
fromdjango_user_agents.utilsimportget_user_agent
@@ -34,41 +34,29 @@
3434

3535

3636
defapi_view(request,method_name):
37-
body=request.body
3837
try:
3938
method=getattr(API(request),method_name)
40-
exceptAttributeError:
41-
log.error('Unknown method %s, body = %s',method_name,body)
42-
returnHttpResponseBadRequest()
43-
try:
39+
body=request.body
4440
body=body.decode('utf8')
45-
exceptUnicodeDecodeError:
46-
log.exception('Failed to decode %s',body)
47-
returnHttpResponseBadRequest()
48-
log.info('API request: method = %s, body = %s',method_name,body)
49-
try:
5041
args=json.loads(body)
51-
exceptValueErrorase:
52-
log.error('JSON decode error: %s',e)
53-
returnHttpResponseBadRequest()
54-
signature=inspect.signature(method)
55-
try:
56-
signature.bind(**args)
57-
exceptTypeErrorase:
58-
log.error(e)
59-
returnHttpResponseBadRequest()
60-
forarg_name,hintinget_type_hints(method).items():
61-
ifarg_name=='return':
62-
continue
63-
arg=args[arg_name]
64-
ifnotisinstance(arg,hint):
65-
log.warning(
66-
'Incorrect type for argument %s = %r of method %s: found %s, expected %s',
67-
arg_name,arg,method_name,arg.__class__.__name__,hint.__name__)
68-
result=method(**args)
69-
ifnotisinstance(result,dict):
70-
result= {'result':result}
71-
returnJsonResponse(result,json_dumps_params=dict(indent=4,sort_keys=True))
42+
forarg_name,hintinget_type_hints(method).items():
43+
ifarg_name=='return':
44+
continue
45+
arg=args[arg_name]
46+
ifnotisinstance(arg,hint):
47+
log.warning(
48+
'Incorrect type for argument %s = %r of method %s: found %s, expected %s',
49+
arg_name,arg,method_name,arg.__class__.__name__,hint.__name__)
50+
result=method(**args)
51+
ifnotisinstance(result,dict):
52+
result= {'result':result}
53+
exceptException:
54+
result=dict(
55+
error=dict(
56+
traceback="".join(traceback.format_exc()),
57+
)
58+
)
59+
returnJsonResponse(result)
7260

7361

7462
classAPI:

‎backend/main/workers/utils.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def internal_error_result():
6464
INTERNAL ERROR IN COURSE:
6565
=========================
6666
67-
{"".join(traceback.format_exception(*sys.exc_info()))}
67+
{"".join(traceback.format_exc())}
6868
6969
This is an error in our code, not yours.
7070
Consider using the Feedback button in the top-right menu

‎frontend/src/App.js‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ import {animateScroll} from "react-scroll";
2525
import{HintsPopup}from"./Hints";
2626
importTogglefrom'react-toggle'
2727
import"react-toggle/style.css"
28-
import{FeedbackModal}from"./Feedback";
28+
import{ErrorModal,FeedbackModal}from"./Feedback";
2929
importbirdseyeIconfrom"./img/birdseye_icon.png";
30-
importhintIconfrom"./img/hint.png";
3130

3231

3332
classAppComponentextendsReact.Component{
@@ -78,6 +77,7 @@ class AppComponent extends React.Component {
7877
solution,
7978
requestingSolution,
8079
user,
80+
rpcError,
8181
}=this.props;
8282
let{
8383
step_index,
@@ -224,6 +224,8 @@ class AppComponent extends React.Component {
224224
<MenuPopup
225225
user={user}
226226
/>
227+
228+
<ErrorModalerror={rpcError}/>
227229
</div>
228230
}
229231
}
@@ -295,5 +297,8 @@ const SettingsModal = ({user}) => (
295297

296298

297299
exportconstApp=connect(
298-
state=>state.book,
300+
state=>({
301+
...state.book,
302+
rpcError:state.rpc.error,
303+
}),
299304
)(AppComponent);

‎frontend/src/Feedback.js‎

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,46 @@ import React from 'react';
22
import{useInput}from"./frontendlib/HookInput";
33
import{rpc}from"./rpc";
44
import{redact}from"./frontendlib/redact"
5+
import{stateSetasrpcStateSet}from"./rpc/store";
6+
importPopupfrom"reactjs-popup";
57

68

7-
exportconstFeedbackModal=({close})=>{
8-
consttitle=useInput('',{
9+
exportconstFeedbackModal=({close, error})=>{
10+
letinitialTitle,instructions;
11+
if(error){
12+
initialTitle=`Error in RPC method${error.method}`;
13+
instructions=<>
14+
<h3>Report error</h3>
15+
<p>
16+
There was an error processing your request on the server!
17+
Please describe what you were just doing and what steps someone can take
18+
to reproduce the problem, then click Submit. Or click Cancel to not send a report.
19+
</p>
20+
<details>
21+
<summary>Click for error details</summary>
22+
<pre>{`
23+
Method:${error.method}
24+
25+
Request data:${JSON.stringify(error.data,null,4)}
26+
27+
${error.traceback}
28+
`}</pre>
29+
</details>
30+
31+
</>
32+
}else{
33+
initialTitle="";
34+
instructions=<>
35+
<h3>Give feedback</h3>
36+
<p>Tell us what you like or don't like! If you're reporting a bug, give a detailed description of the problem:</p>
37+
<ul>
38+
<li>What were you doing before and when the problem occurred?</li>
39+
<li>What steps can someone take to reproduce it?</li>
40+
<li>What do you observe happening, and what do you expect to happen instead?</li>
41+
</ul>
42+
</>
43+
}
44+
consttitle=useInput(initialTitle,{
945
placeholder:'Title',
1046
type:'text',
1147
className:'form-control',
@@ -23,13 +59,7 @@ export const FeedbackModal = ({close}) => {
2359
},'textarea')
2460
return(
2561
<divstyle={{margin:"1em"}}>
26-
<h3>Give feedback</h3>
27-
<p>Tell us what you like or don't like! If you're reporting a bug, give a detailed description of the problem:</p>
28-
<ul>
29-
<li>What were you doing before and when the problem occurred?</li>
30-
<li>What steps can someone take to reproduce it?</li>
31-
<li>What do you observe happening, and what do you expect to happen instead?</li>
32-
</ul>
62+
{instructions}
3363

3464
<div>{title.input}</div>
3565
<br/>
@@ -51,8 +81,30 @@ export const FeedbackModal = ({close}) => {
5181
>
5282
Submit
5383
</button>
84+
85+
<button
86+
className="btn btn-default"
87+
onClick={close}
88+
>
89+
Cancel
90+
</button>
5491
</div>
5592
</div>
5693
);
5794
};
5895

96+
97+
exportconstErrorModal=({error})=>{
98+
if(!error){
99+
returnnull;
100+
}
101+
return(
102+
<Popup
103+
open={true}
104+
closeOnDocumentClick
105+
onClose={()=>rpcStateSet("error",null)}
106+
>
107+
{close=><FeedbackModalclose={close}error={error}/>}
108+
</Popup>
109+
)
110+
};

‎frontend/src/css/main.scss‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@
7474
}
7575
}
7676

77+
.popup-content {
78+
max-height:90vh;
79+
overflow:auto;
80+
}
81+
7782
.my-popup-content {
7883
background:white;
7984
z-index:2;

‎frontend/src/rpc/index.js‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
importaxiosfrom"axios";
2+
import{stateSet}from"./store";
23
// import {finishLoading, statePush, stateSet} from "./store";
34

45
axios.defaults.xsrfCookieName='csrftoken';
@@ -12,13 +13,14 @@ export const rpc = (method, data, onSuccess, onError) => {
1213
`/api/${method}/`,
1314
data,
1415
).then((response)=>{
15-
console.log('Success for RPC method',method);
16-
if(onSuccess){
16+
console.log('Finished RPC method',method);
17+
if(response.data.error){
18+
stateSet("error",{...response.data.error, method, data});
19+
}elseif(onSuccess){
1720
onSuccess(response.data);
1821
}
1922
}).catch((response)=>{
2023
constmessage=`Error for RPC method${method}`;
21-
// dispatch(stateSet('error', message));
2224
console.error(message,response);
2325
if(onError){
2426
onError(response);

‎frontend/src/rpc/store.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const initialState = {
55
error:null,
66
};
77

8-
const{stateSet, statePush, reducer, makeAction}=redact('rpc',initialState);
8+
const{stateSet, statePush, reducer, makeAction}=redact('rpc',initialState,{dispatched:true});
99

1010
export{stateSet,statePush,reducerasrpcReducer};
1111

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp