Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

521 notice parcing failure #586

Merged
merged 32 commits into from
Jan 14, 2023
Merged

Conversation

RollingHog
Copy link
Contributor

#521 adding notice for failed parsing
TESTS NOT FIXED, WAITING FOR OVERALL APPROVAL/CHANGES

UI changes:

  • if there are conf/runners .json files script-server cannot parse, red group called `` will appear in main scripts list

Backend changes:

  • list_configs() now returns mixed List[ Union[ShortConfig, GetShortConfigFailedError] ] list which is filtered in GetScripts()
  • server.py GetScripts() endpoint - now returns JSON {'scripts': scripts, 'failed': failed} where 'failed' is "failed parsing"

Frontend changes (I had no idea what I'm doing):

  • created ScriptFailedGroup.vue closely resembling ScriptListGroup.vue to show list of non-interactive unparsed files

@RollingHog
Copy link
Contributor Author

And I can't see exactly which error in pretty big Travis feed fails. Never used tests in Python, sry.

@bugy
Copy link
Owner

bugy commented Oct 15, 2022

Hi @RollingHog, thanks for your changes. I would see it implemented a bit differently:

  • Instead of returning completely different type from list_configs, I think we should just return existing short_config type with a new field "parsing_failed: true". Returning 2 completely different types from a method is more difficult to read and maintain
  • if a script file contains text: "allows_users", then it shouldn't be listed at all (otherwise users might see scripts, which are not intended for them)
  • In all other places in config_service, if we are loading extended model for a config, we should check this flag as well. I.e. if a user tries to load and display such a script, we would show proper error
  • On UI, instead of using a separate group, I would suggest to show the script as it is, but: make the text red and add error icon to it
  • Admin UI should be adjusted as well, i.e. the config should be listed, but shouldn't be clickable, and shown as read

Regarding the tests, you can run them using the follwing command from src folder:
python3 -m unittest discover -s tests -p "*.py" -t .

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 15, 2022

Oookay.

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 15, 2022

Will update this during work

  • Instead of returning completely different type from list_configs, I think we should just return existing short_config type with a new field "parsing_failed: true".
  • if a script file contains text: "allowed_users", then it shouldn't be listed at all (otherwise users might see scripts, which are not intended for them)
  • In all other places in config_service, if we are loading extended model for a config, we should check this flag as well. I.e. if a user tries to load and display such a script, we would show proper error
  • On UI, instead of using a separate group, I would suggest to show the script as it is, but: make the text red and add error icon to it
  • Admin UI should be adjusted as well, i.e. the config should be listed, but shouldn't be clickable, and shown as read

Kinda. Not sure what is "shown as read"

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 17, 2022

Questions emerged:

  • On allowed_users: should I regexp JSON server-side and return something like "possibly restricted script" instead of its real filename for non-admin users?
  • On Exceptions: should I hide their tracebacks from log since this is considered as acceptable option now? Already did, its annoying.

@bugy
Copy link
Owner

bugy commented Oct 17, 2022

On allowed_users: should I regexp JSON server-side and return something like "possibly restricted script" instead of its real filename for non-admin users?

Yes please, please check the file (I think regex is not needed, just check, that the file content contains "allowed_users" string)
However, do not show anything to non-admin users at all. The file might be supposed to be hidden from them

@bugy
Copy link
Owner

bugy commented Oct 17, 2022

For the stacktrace, I would suggest to log it. It will cause some noise, but it's easier to investigate having traceback

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 18, 2022

For the stacktrace, I would suggest to log it. It will cause some noise, but it's easier to investigate having traceback

I meant only for "cannot parse" error of course. Still log?

And about files. I think a note "some file with restricted access is malformed" will be good, wont it? Or there is some reason to fully hide this info?

@bugy
Copy link
Owner

bugy commented Oct 18, 2022

I meant only for "cannot parse" error of course. Still log?

yes, it can still provide some hints on what's wrong with the file.

I think a note "some file with restricted access is malformed" will be good, wont it? Or there is some reason to fully hide this info?

Not for normal users. Any restricted information should be hidden from users, to avoid any leaks. Even if it's only a file name

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 18, 2022

Even if it's only a file name

No no no! What I planned to do was replacing filename with "file with possibly restricted access" server-side. So users see that something is wrong (and can eg notify admin) but don't know what exactly.

yes, it can still provide some hints on what's wrong with the file.

You mean that error message about exact line where problem is? Okay.

@bugy
Copy link
Owner

bugy commented Oct 18, 2022

What I planned to do was replacing filename with "file with possibly restricted access" server-side.

Ah, I see. I thought, that you wanted to display filename and show the error
May be in this case, it would be just enough to show how many files failed to load, e.g. in the script list UI it would look like this:

  • Script 1
  • Script 2
  • Script 3
  • (red) N files failed to load

@RollingHog
Copy link
Contributor Author

RollingHog commented Oct 22, 2022

All done. Now trying to understand testing command output to fix the tests.

src/config/config_service.py Outdated Show resolved Hide resolved
@@ -191,7 +196,10 @@ def load_script(path, content):
return None

return short_config
except:
except json.decoder.JSONDecodeError:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add logging for the error, to help admin debugging the issue.

Copy link
Contributor Author

@RollingHog RollingHog Nov 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't logging already present there?.. Line 200. It provides all info including exact mistake in JSON grammar.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I wrote the comment, before you added the logging :) thanks

src/config/config_service.py Show resolved Hide resolved
src/config/config_service.py Show resolved Hide resolved
Comment on lines 259 to 260
if name == path:
failed_short_config = create_failed_ShortConfig(path)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that we should do smth like:

failed_short_config = create_failed_ShortConfig(path)
if name == failed_short_config.name:
  ...

I.e. we shouldn't compare the path to the name directly, because the name doesn't contain .json extension and there can be some other rules in the future

web-src/src/main-app/components/scripts/ScriptListItem.vue Outdated Show resolved Hide resolved
.scripts-list .collection-item .menu-item-state.finished > .check-icon {
display: block;
}

.scripts-list .collection-item .menu-item-state.finished > .preloader-wrapper {
.scripts-list .collection-item .menu-item-state.finished > .preloader-wrapper,
.scripts-list .collection-item .menu-item-state.finished > .failed-icon {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need to duplicate this display:none multiple times.
You can define it once, smth like:

.scripts-list .collection-item .menu-item-state > .failed-icon {
  display: none;
}

And it should be enough.
I do not know why I copied it multiple times for check icon and preload wrapper.

Copy link
Contributor Author

@RollingHog RollingHog Nov 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what to do with that, sorry.

Comment on lines 338 to 341
if (error.code === 422) {
commit('SET_ERROR', `${CANNOT_PARSE_ERROR_PREFIX} "${selectedScript}"`);
return;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to remove custom handling here. Script server can start sending 422 for other cases as well, so always showing "parsing error" is not good. We should always rely on error.reason, which is provided by the server

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, how should I aquire that error then?

src/model/script_config.py Outdated Show resolved Hide resolved
@@ -191,7 +196,10 @@ def load_script(path, content):
return None

return short_config
except:
except json.decoder.JSONDecodeError:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I wrote the comment, before you added the logging :) thanks

Comment on lines 201 to 202
failed_short_config = create_failed_short_config(path)
return failed_short_config
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
failed_short_config = create_failed_short_config(path)
return failed_short_config
return create_failed_short_config(path)

src/config/config_service.py Show resolved Hide resolved
except json.decoder.JSONDecodeError:
if name == path:
failed_short_config = create_failed_ShortConfig(path)
raise StopIteration(ConfigSearchResult(failed_short_config, path, None))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not done. The exception won't be thrown here. What I meant is to add the following code after
configs = self._visit_script_configs(find_and_load)

        if(search_result.short_config.parsing_failed == True):
          raise BadConfigFileException()

I.e. do it only once in _find_config, instead of duplicating it in load_config_model and load_config


def create_failed_ShortConfig(path):
failed_short_config = ShortConfig()
failed_short_config.name = path
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not done

failed_short_config.name = path
with open(path) as f:
if '"allowed_users"' in f.read():
failed_short_config.name = 'file with possibly restricted access (path hash ' + hex(hash(path)) + ')'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use some shorter name? 😅 Probably not longer than 20 characters

@@ -184,6 +184,9 @@ def load_model():
except ConfigNotAllowedException:
self.close(code=403, reason='Access to the script is denied')
return None
except BadConfigFileException:
self.close(code=BadConfigFileException.HTTP_CODE, reason=BadConfigFileException.VERBOSE_ERROR)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, please use exception.message here

Comment on lines 12 to 13
<router-link :to="script.path" append
:key="script.name"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<router-link :to="script.path" append
:key="script.name"
<router-link :to="script.path"
append
:key="script.name"

@bugy
Copy link
Owner

bugy commented Jan 14, 2023

@RollingHog I'm so sorry, I totally forgot about this PR. I thought that we finished it.
I'm merging it to master now, thanks for your work!

@bugy bugy merged commit f7fb01a into bugy:master Jan 14, 2023
@RollingHog
Copy link
Contributor Author

Well, I hope it helped.

@bugy bugy added this to the 1.18.0 milestone Aug 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants