|
3 | 3 |
|
4 | 4 | import re |
5 | 5 | from copy import deepcopy |
6 | | -from typing import Any, Mapping, cast |
| 6 | +# (canada fork only): handle all errors in resource actions |
| 7 | +# TODO: upstream contrib?? |
| 8 | +from typing import Any, Mapping, cast, Tuple, Dict |
7 | 9 |
|
8 | 10 |
|
9 | 11 | from ckan.logic import NotFound |
@@ -73,3 +75,77 @@ def prettify(field_name: str): |
73 | 75 | else: |
74 | 76 | summary[_(prettify(key))] = error[0] |
75 | 77 | return summary |
| 78 | + |
| 79 | + |
| 80 | +# (canada fork only): handle all errors in resource actions |
| 81 | +# TODO: upstream contrib?? |
| 82 | +def resource_validation_errors( |
| 83 | + error_dict: ErrorDict, |
| 84 | + action: str, |
| 85 | + pkg_dict: Dict[str, Any], |
| 86 | + resource_index: int = -1) -> Tuple[Dict[str, Any], str]: |
| 87 | + """ |
| 88 | + Returns a modified (error_dict, error_summary) with errors from the |
| 89 | + resource_index resource fields in error_dict, errors from the dataset |
| 90 | + fields under error_dict['dataset'] and errors from other resource |
| 91 | + fields under error_dict['resources'][resource_id]. |
| 92 | + """ |
| 93 | + new_error_dict = dict(error_dict) |
| 94 | + # define out own error summaries so we can have |
| 95 | + # a more customized structure to the ErrorDict |
| 96 | + error_summaries = [] |
| 97 | + if action == 'delete': |
| 98 | + # special case for deleting as there is no index |
| 99 | + # for a non-existent resource in the pkg_dict. |
| 100 | + current_res_error_dict = False |
| 101 | + else: |
| 102 | + current_res_error_dict = cast("list[ErrorDict]", error_dict['resources'])[resource_index] |
| 103 | + if current_res_error_dict: |
| 104 | + # if there are errors for the current resource |
| 105 | + # let's raise them to the user first. |
| 106 | + new_error_dict = dict(current_res_error_dict) |
| 107 | + if not current_res_error_dict and 'resources' in error_dict and isinstance(error_dict['resources'], list): |
| 108 | + # compile the other resource errors |
| 109 | + new_error_dict = {'resources': {}} |
| 110 | + for key, res_error_dict in enumerate(error_dict['resources']): |
| 111 | + if not res_error_dict: |
| 112 | + continue |
| 113 | + if key <= len(pkg_dict['resources']): # case for resource_delete |
| 114 | + errored_resource = pkg_dict['resources'][key] |
| 115 | + if errored_resource.get('id'): |
| 116 | + new_error_dict['resources'][errored_resource.get('id')] = res_error_dict |
| 117 | + if res_error_dict: |
| 118 | + if action == 'create' or action == 'update': |
| 119 | + error_summaries.append( |
| 120 | + _('Could not create or update resource because another resource in ' |
| 121 | + 'this dataset has errors: {}').format(errored_resource['id'])) |
| 122 | + elif action == 'delete': |
| 123 | + error_summaries.append( |
| 124 | + _('Could not delete resource because another resource in ' |
| 125 | + 'this dataset has errors: {}').format(errored_resource['id'])) |
| 126 | + elif action == 'reorder': |
| 127 | + error_summaries.append( |
| 128 | + _('Could not reorder resources because a resource in ' |
| 129 | + 'this dataset has errors: {}').format(errored_resource['id'])) |
| 130 | + if error_dict: |
| 131 | + # compile the dataset errors |
| 132 | + for key, errors in error_dict.items(): |
| 133 | + if key == 'resources': |
| 134 | + continue |
| 135 | + if 'dataset' not in new_error_dict: |
| 136 | + new_error_dict['dataset'] = {} |
| 137 | + new_error_dict['dataset'][key] = errors |
| 138 | + if 'dataset' in new_error_dict: |
| 139 | + if action == 'create' or action == 'update': |
| 140 | + error_summaries.append( |
| 141 | + _('Could not create or update resource because ' |
| 142 | + 'the dataset has errors')) |
| 143 | + elif action == 'delete': |
| 144 | + error_summaries.append( |
| 145 | + _('Could not delete resource because ' |
| 146 | + 'the dataset has errors')) |
| 147 | + elif action == 'reorder': |
| 148 | + error_summaries.append( |
| 149 | + _('Could not reorder resources because ' |
| 150 | + 'the dataset has errors')) |
| 151 | + return new_error_dict, _('; ').join(error_summaries) |
0 commit comments