Diff Doctor
Review Request #6993 — Created Feb. 27, 2015 and discarded
This project attempts to provide a more helpful user interface when a patch fails.
A patch fails when either components: the patch file, or the to-be-patched file is corrupt. Less likely, linux patch can also fail.
The first step of this project is to catch the error in patch() as a PatchError, and provide the user a download link to the reject files as a ZIP file. This link will be implemented as a Django view.
The second step of this project involves displaying the reject files (original, diff and .rej files), rendered as in-line HTML with Pygments, in place of the error traceback.
Manual testing has been done, for:
- Normal review requests (no diff error), returns a 404
- Review request containing a failed patch, with failure due to faulty original-file (corrupted endpoints in 3rd party services with their own repositories, like gitweb, or cgit). These will return a 404 page
- Review request containing a failed patch, with failure due to patch() itself. I have only managed to replicate this by manually uploading a corrupted diff file, but am unaware of how this could happen in a real use case. The in-line reject files show up as expected in the traceback box, and the .zip download is functional
Description | From | Last Updated |
---|---|---|
redefinition of unused 'get_object_or_404' from line 18 |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
Col: 80 E501 line too long (96 > 79 characters) |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
Col: 80 E501 line too long (100 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (86 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
Col: 43 E231 missing whitespace after ':' |
reviewbot | |
Col: 22 E231 missing whitespace after ':' |
reviewbot | |
Col: 5 E303 too many blank lines (2) |
reviewbot | |
Col: 35 E128 continuation line under-indented for visual indent |
reviewbot | |
Col: 80 E501 line too long (94 > 79 characters) |
reviewbot | |
Col: 34 E231 missing whitespace after ':' |
reviewbot | |
Col: 25 E231 missing whitespace after ':' |
reviewbot | |
Col: 28 E231 missing whitespace after ':' |
reviewbot | |
Col: 80 E501 line too long (88 > 79 characters) |
reviewbot | |
Col: 34 E231 missing whitespace after ':' |
reviewbot | |
Col: 25 E231 missing whitespace after ':' |
reviewbot | |
Col: 28 E231 missing whitespace after ':' |
reviewbot | |
Col: 80 E501 line too long (88 > 79 characters) |
reviewbot | |
redefinition of unused 'get_object_or_404' from line 18 |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
Col: 80 E501 line too long (96 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (100 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (86 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
Col: 22 E231 missing whitespace after ':' |
reviewbot | |
Col: 43 E231 missing whitespace after ':' |
reviewbot | |
Col: 5 E303 too many blank lines (2) |
reviewbot | |
Col: 35 E128 continuation line under-indented for visual indent |
reviewbot | |
Col: 80 E501 line too long (94 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
Col: 44 W292 no newline at end of file |
reviewbot | |
Col: 80 E501 line too long (81 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (82 > 79 characters) |
reviewbot | |
redefinition of unused 'get_object_or_404' from line 18 |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
Col: 80 E501 line too long (96 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (82 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (100 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (86 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (90 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (89 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (89 > 79 characters) |
reviewbot | |
local variable 'new_file' is assigned to but never used |
reviewbot | |
Col: 80 E501 line too long (91 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (93 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (88 > 79 characters) |
reviewbot | |
Col: 17 E225 missing whitespace around operator |
reviewbot | |
Col: 38 E231 missing whitespace after ':' |
reviewbot | |
Col: 29 E231 missing whitespace after ':' |
reviewbot | |
Col: 32 E231 missing whitespace after ':' |
reviewbot | |
Col: 80 E501 line too long (89 > 79 characters) |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
Col: 80 E501 line too long (80 > 79 characters) |
reviewbot | |
redefinition of unused 'DiffSet' from line 49 |
reviewbot | |
redefinition of unused 'get_original_file' from line 43 |
reviewbot | |
redefinition of unused 'get_patched_file' from line 43 |
reviewbot | |
Undo this change. |
brennie | |
Use all available line width (79 characters). |
brennie | |
We use single quotes. Also, if you wrap the string in parenthesis you can leave out the backslashes (which are … |
brennie | |
This should all be lined up with the opening quote on the previous lines. |
brennie | |
You want to do: super(PatchError, self).__init__(error_msg) and it is usually done at the start of the overriden __init__. |
brennie | |
Who did what can be shown with git blame so this isn't really needed. |
brennie | |
This method needs a docstring. |
brennie | |
This seems like good information for the docstring. |
brennie | |
You should use from django.utils.six import StringIO. It would probably be better to use cStringIO à la from django.utils.six.moves import … |
brennie | |
Order these alphabetically. |
brennie | |
Order these alphabetically. |
brennie | |
This class needs a docstring. |
brennie | |
This method needs a docstring. |
brennie | |
You can format this as: self.review_request, response = _find_review_request( request, review_request_id, None) |
brennie | |
Why does this assign to self if there are no other methods in that will use it? |
brennie | |
Does this take into account local sites? |
brennie | |
Comments generally are written in second person (We...) or like follows: There shouldn't be more than one diff returned. Also, … |
brennie | |
Since the error handling is the same you can do except (FileNotFoundError, SCMError) as e: # common error handling |
brennie | |
You don't implement render_to_response so why are you explicitly invoking the super method? Also, this formatting is wonky. How about: … |
brennie | |
Same as previous comment. |
brennie | |
We use single quotes for strings. Also this will have to be localized. |
brennie | |
It would probably be better to use a StreamingHttpResponse here so we don't block while the zip is built. |
brennie | |
I mentioned in my last review that since you are not using overriding render_to_response, you should just use self.render_to_response. Since … |
brennie | |
Single quotes for strings. Should have a trailing comma. |
brennie | |
Single quotes for strings. Should have a trailing comma. |
brennie | |
Single quotes for strings. Should have a trailing comma. The %-substitution should happen outside the call to _. Otherwise, multiple … |
brennie | |
We use single quotes for strings. |
brennie | |
This method needs a docstring. |
brennie | |
This information seems like it would be good for the docstring instead of as just a comment. |
brennie | |
No blank line here. |
brennie | |
The braces should be on their own lines. Each key-value pair should be its own line. The last key-value pair … |
brennie | |
We use single quotes for strings. |
brennie | |
Strings need to be translated. Here and elsewhere. I also don't think this is a good title -- perhaps just … |
brennie | |
Why not just {% trans "There was a problem with your patch." %}. Also, missing a period. |
brennie | |
You can just use {% trans error.msg %} |
brennie | |
This doesn't seem like a good string to put here. Also, make sure all strings are localized. |
brennie | |
is {{error}} expected to be HTML? If not, just use {% trans error %}. |
brennie | |
Col: 13 E123 closing bracket does not match indentation of opening bracket's line |
reviewbot | |
Col: 13 E123 closing bracket does not match indentation of opening bracket's line |
reviewbot | |
'HttpResponseServerError' imported but unused |
reviewbot | |
'render' imported but unused |
reviewbot | |
'FileNotFoundError' imported but unused |
reviewbot | |
'SCMError' imported but unused |
reviewbot | |
Imports should be in alphabetical order. |
chipx86 | |
Can you add a docstring for this? |
chipx86 | |
Considering we'll only be accessing this data if we're downloading it, it's a bit expensive to do every time we're … |
chipx86 | |
Comments should be in sentence casing and end with a period. |
chipx86 | |
No need for mode=. You can just pass 'r'. |
chipx86 | |
We should localize this. |
chipx86 | |
Blank line before this. |
chipx86 | |
This change isn't relevant, and should be undone. |
chipx86 | |
Missing a trailing period. |
chipx86 | |
This needs to follow the guidelines for docstrings we have elsewhere. No :param: or :return:, either. |
chipx86 | |
Must be in alphabetical order. |
chipx86 | |
Should use dashes instead of underscores in the URL. This is also missing a $ at the end of the … |
chipx86 | |
We use dashes instead of underscores for URL names. |
chipx86 | |
The text must be on the first line. Instead of "This class ...", say something like "Downloads debug information for … |
chipx86 | |
This information is already in the function, and is more of an implementation detail for the URL structure. I would … |
chipx86 | |
Make sure to follow the proper docstring format: """One-line summary Multi-line description. """ |
chipx86 | |
Your code isn't actually streaming the content, so there's no reason to use a StreamingHttpResponse. A StreamingHttpResponse would be useful … |
chipx86 | |
There's not much benefit to using a format string here, if we're hard-coding the string to put in there. |
chipx86 | |
If there's a different sort of exception, we need to know about it. This should definitely remain a 500. It's … |
chipx86 | |
This needs a docstring. |
chipx86 | |
You can write this as one statement: return local_site_reverse( 'patch-download', request=self.request, kwargs={ ... }) |
chipx86 | |
That's not adding anything beyond the name of the function. The docstring should explain what information is being added. |
chipx86 | |
Needs to be proper sentences. |
chipx86 | |
This would be better as: error_data = ( (e.file, 'old_file'), ... ) for code, context_attr in error_data: ... |
chipx86 | |
Make sure the indentation of all these template tags are correct, with respect to any parent template tags. |
chipx86 | |
#oldfile is going to conflict with other errors on the page. Each ID needs to be unique. Note how we … |
chipx86 | |
It's best to call mark_safe() around the data being fed into the template, when we know it's safe. |
chipx86 | |
These lines are way too short. Also, no spaces inside the {{...}}. |
chipx86 | |
'HttpResponseServerError' imported but unused |
reviewbot | |
Col: 80 E501 line too long (82 > 79 characters) |
reviewbot | |
Col: 43 E128 continuation line under-indented for visual indent |
reviewbot | |
Col: 80 E501 line too long (81 > 79 characters) |
reviewbot | |
'HttpResponseServerError' imported but unused |
reviewbot | |
Col: 1 E302 expected 2 blank lines, found 1 |
reviewbot |
-
Tool: PEP8 Style Checker Processed Files: reviewboard/diffviewer/views.py reviewboard/reviews/urls.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: Pyflakes Processed Files: reviewboard/diffviewer/views.py reviewboard/reviews/urls.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html
-
-
-
-
-
Thanks for getting the draft of this change up. Make sure you prefix the summary with "[WIP]".
It looks like this is still in the very early phases. I have a few comments to help with the next steps:
- The files in
reviewboard/diffviewer/
know nothing about review requests, and that must not change. You won't want to generate the URLs in there, but rather in the templates, which do have access to the review request. You'll use the{% url %}
tag there. - There's not really any information in this change as to why your custom view did not work. Can you let me know what issues you hit?
- In our codebase, the
diffviewer
module is meant to be consumed by thereviews
module. The URLs will all live inreviews/urls.py
, and map to views inreviews
that consume views or other code fromdiffviewer
. You'll need to follow the same pattern. Links in the template would map to URLs/views inreviews
, which would have access to the review request (same as any other views in there). Those views would then make use of code fromdiffviewer
to fetch the files from the result of apatch()
call, and return them.
What I want to see in the next revision is some work toward this. Instead of testing code with your name in it, try to work toward a working implementation that, for now, just returns a dummy file (something generated in code). You should have:
- A URL in
reviews
for this. I suggest putting this in thedowload_diff_urls
section as'^patch-results/$
'. - A view in
reviews
for downloading the debug information for a diff. This would be what the URL maps to. This would get the matching review request and, for now, return some dummy content. Look at the other views mapped from those neighboring URLs. - A link in the template for "Download patch results" pointing to that URL
This will give you something that should be testable. You should be able to click that link and get that dummy content as something that's downloadable.
The next step is to create a new exception in
diffviewer/errors.py
calledPatchFailedError
. This should take the same arguments currently fed into the exception inpatch()
, and should generate that string by itself. Those arguments should also be accessible to any code that catches the exception. They're just variables on the instance of the exception at that point.After that, it's time to modify your new view to call
patch()
, catch the exception, and then create an archive of the contents of that temp directory mentioned in the exception. Python has modules built-in for creating archives.This would comprise the introductory step to this project.
- The files in
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/views.py reviewboard/reviews/urls.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/views.py reviewboard/reviews/urls.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Commit:
-
3a0c39547594dc8e5e8120cb6ea52a4d57619125b6bdc1f483c8b1d5fa89899e7587dbc9d1f60938
- Diff:
-
Revision 4 (+185 -13)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Hi Tien. This is just a reminder that when you upload a new diff revision, you should mark old issues from Review Bot as fixed (if you fixed them) or dropped. Otherwise its hard to keep track of how many issues are with the current diff revisision. Please also fix the errors that Review Bot complains about.
- Commit:
-
b6bdc1f483c8b1d5fa89899e7587dbc9d1f6093881d9a173ca1e287a91790b5bc81307bc91395dda
- Diff:
-
Revision 5 (+165 -17)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
-
- Change Summary:
-
Copy paste from commit message:
Move location of diff file rejection download Summary of changes: - Deleted PatchErrorView, instead rendering content in ReviewsDiffFragmentView - Simplified get() function in PatchErrorDownloadView - Add exception handling for SCMErrors (which are in turn thrown when HTTPErrors are thr - Added a wrapper in DiffFragmentView to let subclasses insert extra context variables w - Change template code in diff_fragment_error.html to display Diff Doctor information
- Description:
-
~ Seeing if I'm even on the right track
~ WIP
-
Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
-
Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
-
- Summary:
-
(WIP) Diff Doctor DraftDiff Doctor - Stage 1
- Description:
-
~ WIP
~ This project attempts to provide a more helpful user interface when a patch fails.
+ A patch fails when either components: the patch file, or the to-be-patched file is corrupt. Less likely, linux patch can also fail. + The first step of this project is to catch the error in patch() as a PatchError, and provide the user a download link to the reject files as a ZIP file. This link will be implemented as a Django view. - Testing Done:
-
+ Manual testing has been done, for:
+ - Normal review requests (no diff error) + - Review request containing a failed patch, with failure due to faulty original-file (corrupted endpoints in 3rd party services with their own repositories, like gitweb, or cgit) + - Review request containing a failed patch, with failure due to patch() itself. I have only managed to replicate this by manually uploading a corrupted diff file, but am unaware of how this could happen in a real use case. - Commit:
-
81d9a173ca1e287a91790b5bc81307bc91395dda84ce8178e429f05ed75001f0ed87c983882b9854
- Diff:
-
Revision 8 (+161 -19)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
-
We use single quotes. Also, if you wrap the string in parenthesis you can leave out the backslashes (which are ugly and can cause problems if there is trailing whitespace), e.g.,
error_msg = ("line 1" "line 2" "..." "line n")
-
-
You want to do:
super(PatchError, self).__init__(error_msg)
and it is usually done at the start of the overriden
__init__
. -
-
-
-
You should use
from django.utils.six import StringIO
. It would probably be better to usecStringIO
Ă lafrom django.utils.six.moves import cStringIO
-
-
-
-
-
You can format this as:
self.review_request, response = _find_review_request( request, review_request_id, None)
-
-
-
Comments generally are written in second person (
We...
) or like follows:There shouldn't be more than one diff returned.
Also, since we are assuming this, it is probably good to assert our assumption.
diff_files = get_diff_files(diffset, filediff, None, request) assert len(diff_files) == 1 diff_file = diff_files[0]
-
Since the error handling is the same you can do
except (FileNotFoundError, SCMError) as e: # common error handling
-
You don't implement
render_to_response
so why are you explicitly invoking the super method?Also, this formatting is wonky. How about:
return super(PatchErrorDownloadView, self).render_to_response(
{
'error': e
}) -
-
-
It would probably be better to use a
StreamingHttpResponse
here so we don't block while the zip is built. -
-
-
-
-
The braces should be on their own lines. Each key-value pair should be its own line. The last key-value pair should have a trailing comma.
We use single quotes for strings.
-
-
Strings need to be translated. Here and elsewhere. I also don't think this is a good title -- perhaps just Diff Doctor?
-
- Commit:
-
84ce8178e429f05ed75001f0ed87c983882b9854bc5ed4d8e69eba54dbc60bae5068809747bd22d1
- Diff:
-
Revision 9 (+219 -50)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
- Commit:
-
bc5ed4d8e69eba54dbc60bae5068809747bd22d1f732cd153ed94bbe590186d83e5dcc54dbb0ebfb
- Diff:
-
Revision 11 (+219 -50)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
I mentioned in my last review that since you are not using overriding
render_to_response
, you should just useself.render_to_response
. Since you are subclassing from theTemplateView
,self.render_to_response
will have the exact same definition asTemplateView.render_to_response
and will make for less line noise.Also, you can put the
{
on the previous line, like so:return self.render_to_response({ 'foo': 'bar', })
-
-
-
Single quotes for strings. Should have a trailing comma.
The
%
-substitution should happen outside the call to_
. Otherwise, multiple strings have to be translted instead of one containing a %s.You are also missing a trailing period in the string.
-
-
-
- Commit:
-
f732cd153ed94bbe590186d83e5dcc54dbb0ebfb0294ca350a7f71ae83fdabff00b35f55a439506a
- Diff:
-
Revision 12 (+219 -50)
-
Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
- Commit:
-
0294ca350a7f71ae83fdabff00b35f55a439506ae04e497607a5ed16d92490d6148c3ad9db01187e
- Diff:
-
Revision 13 (+206 -26)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/templates/diffviewer/patch_error.html
-
-
-
- Commit:
-
e04e497607a5ed16d92490d6148c3ad9db01187e755217e068c4a98bc57c7047b259a9d8b99757b6
- Diff:
-
Revision 14 (+189 -27)
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/TEST Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html reviewboard/TEST
-
-
Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/diffviewer/renderers.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html
- Summary:
-
Diff Doctor - Stage 1Diff Doctor
- Description:
-
This project attempts to provide a more helpful user interface when a patch fails.
A patch fails when either components: the patch file, or the to-be-patched file is corrupt. Less likely, linux patch can also fail. ~ The first step of this project is to catch the error in patch() as a PatchError, and provide the user a download link to the reject files as a ZIP file. This link will be implemented as a Django view. ~ The first step of this project is to catch the error in patch() as a PatchError, and provide the user a download link to the reject files as a ZIP file. This link will be implemented as a Django view. + The second step of this project involves displaying the reject files (original, diff and .rej files), rendered as in-line HTML with Pygments, in place of the error traceback. - Testing Done:
-
Manual testing has been done, for:
~ - Normal review requests (no diff error) ~ - Review request containing a failed patch, with failure due to faulty original-file (corrupted endpoints in 3rd party services with their own repositories, like gitweb, or cgit) ~ - Review request containing a failed patch, with failure due to patch() itself. I have only managed to replicate this by manually uploading a corrupted diff file, but am unaware of how this could happen in a real use case. ~ - Normal review requests (no diff error), returns a 404 ~ - Review request containing a failed patch, with failure due to faulty original-file (corrupted endpoints in 3rd party services with their own repositories, like gitweb, or cgit). These will return a 404 page ~ - Review request containing a failed patch, with failure due to patch() itself. I have only managed to replicate this by manually uploading a corrupted diff file, but am unaware of how this could happen in a real use case. The in-line reject files show up as expected in the traceback box, and the .zip download is functional
-
Looking good, overall!
The majority of the issues here are more about following existing style conventions, and should be easy to clean up quickly.
I'd love to see some screenshots on the review request as well.
-
-
-
Considering we'll only be accessing this data if we're downloading it, it's a bit expensive to do every time we're throwing an error. Instead, the exception should be providing all the information needed for the download view to read and return the file contents.
-
-
-
-
-
-
-
This needs to follow the guidelines for docstrings we have elsewhere. No
:param:
or:return:
, either. -
-
Should use dashes instead of underscores in the URL.
This is also missing a
$
at the end of the pattern. -
-
The text must be on the first line.
Instead of "This class ...", say something like "Downloads debug information for a failed patch."
-
This information is already in the function, and is more of an implementation detail for the URL structure. I would focus the docstring on the sort of information provided by the view, and not the parameters to the URL.
-
-
Your code isn't actually streaming the content, so there's no reason to use a
StreamingHttpResponse
.A
StreamingHttpResponse
would be useful if you were to pass an instance of some sort of class that was fetching the contents of files on-demand. It could be written this way, but we've spent some time on this for another project, and it's just not easy for zip files.So, in this case, I'd use a
HttpResponse
. -
There's not much benefit to using a format string here, if we're hard-coding the string to put in there.
-
If there's a different sort of exception, we need to know about it. This should definitely remain a 500.
It's fine to just log the exception information here and re-raise. That way, the caller will see a 500 when something unexpected goes wrong, and an administrator can look in the log file for the details.
-
-
You can write this as one statement:
return local_site_reverse( 'patch-download', request=self.request, kwargs={ ... })
-
That's not adding anything beyond the name of the function. The docstring should explain what information is being added.
-
-
This would be better as:
error_data = ( (e.file, 'old_file'), ... ) for code, context_attr in error_data: ...
-
Make sure the indentation of all these template tags are correct, with respect to any parent template tags.
-
#oldfile
is going to conflict with other errors on the page. Each ID needs to be unique. Note how we did it before with the details link.Also, the text needs to be localized.
Same below.
-
-
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html
-
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html
-
-
-
-
-
-
Tool: Pyflakes Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html Tool: PEP8 Style Checker Processed Files: reviewboard/reviews/views.py reviewboard/reviews/urls.py reviewboard/diffviewer/errors.py reviewboard/diffviewer/views.py reviewboard/diffviewer/diffutils.py Ignored Files: reviewboard/templates/diffviewer/diff_fragment_error.html