brilliance-admin 0.44.4__py3-none-any.whl → 0.44.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ from brilliance_admin.utils import DataclassBase, SupportsStr
10
10
  class FieldError(DataclassBase, Exception):
11
11
  message: SupportsStr = None
12
12
  code: str | None = None
13
+ field_slug: str | None = None
13
14
 
14
15
  def __post_init__(self):
15
16
  if not self.message and not self.code:
@@ -30,12 +30,12 @@ class SQLAlchemyAdminListMixin:
30
30
 
31
31
  if list_data.ordering and ordering not in self.ordering_fields:
32
32
  msg = f'Ordering "{ordering}" is not allowed; available options: {self.ordering_fields} default_ordering: {self.default_ordering}'
33
- raise FieldError(message=msg)
33
+ raise FieldError(message=msg, field_slug='ordering')
34
34
 
35
35
  column = getattr(self.model, ordering, None)
36
36
  if not isinstance(column, InstrumentedAttribute):
37
37
  msg = f'{type(self).__name__} ordering field "{ordering}" not found in model {self.model}'
38
- raise FieldError(message=msg)
38
+ raise FieldError(message=msg, field_slug='ordering')
39
39
 
40
40
  return stmt.order_by(direction(column))
41
41
 
@@ -122,18 +122,10 @@ class SQLAlchemyAdminListMixin:
122
122
  )
123
123
  raise AdminAPIException(APIError(message=_('errors.filters_exception'), code='filters_exception'), status_code=500) from e
124
124
 
125
- data = []
126
-
127
125
  try:
128
126
  async with self.db_async_session() as session:
129
127
  total_count = await session.scalar(count_stmt)
130
128
  records = (await session.execute(stmt)).scalars().all()
131
- for record in records:
132
- line = await self.table_schema.serialize(
133
- record,
134
- extra={"record": record, "user": user},
135
- )
136
- data.append(line)
137
129
 
138
130
  except ConnectionRefusedError as e:
139
131
  logger.exception(
@@ -176,4 +168,29 @@ class SQLAlchemyAdminListMixin:
176
168
  APIError(message=msg, code='db_error_list'), status_code=500,
177
169
  ) from e
178
170
 
171
+ try:
172
+ data = []
173
+ for record in records:
174
+ line = await self.table_schema.serialize(
175
+ record,
176
+ extra={"record": record, "user": user},
177
+ )
178
+ data.append(line)
179
+
180
+ except FieldError as e:
181
+ logger.exception(
182
+ 'SQLAlchemy %s list %s serialize field error: %s',
183
+ type(self).__name__, self.model.__name__, e,
184
+ )
185
+ msg = _('serialize_error.field_error') % {'error': e.message, 'field_slug': e.field_slug}
186
+ raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
187
+
188
+ except Exception as e:
189
+ logger.exception(
190
+ 'SQLAlchemy %s list %s serialize error: %s',
191
+ type(self).__name__, self.model.__name__, e,
192
+ )
193
+ msg = _('serialize_error.unexpected_error') % {'error': str(e)}
194
+ raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
195
+
179
196
  return schema.TableListResult(data=data, total_count=int(total_count or 0))
@@ -36,18 +36,6 @@ class SQLAlchemyAdminRetrieveMixin:
36
36
  try:
37
37
  async with self.db_async_session() as session:
38
38
  record = (await session.execute(stmt)).scalars().first()
39
- data = await self.table_schema.serialize(
40
- record,
41
- extra={"record": record, "user": user},
42
- )
43
-
44
- except FieldError as e:
45
- logger.exception(
46
- 'SQLAlchemy %s retrieve %s #%s field error: %s',
47
- type(self).__name__, self.model.__name__, pk, e,
48
- )
49
- msg = _('errors.serialize_field_error') % {'error': e.message}
50
- raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
51
39
 
52
40
  except Exception as e:
53
41
  logger.exception(
@@ -66,6 +54,27 @@ class SQLAlchemyAdminRetrieveMixin:
66
54
  status_code=400,
67
55
  )
68
56
 
57
+ try:
58
+ data = await self.table_schema.serialize(
59
+ record,
60
+ extra={"record": record, "user": user},
61
+ )
62
+ except FieldError as e:
63
+ logger.exception(
64
+ 'SQLAlchemy %s retrieve %s #%s serialize field error: %s',
65
+ type(self).__name__, self.model.__name__, pk, e,
66
+ )
67
+ msg = _('serialize_error.field_error') % {'error': e.message, 'field_slug': e.field_slug}
68
+ raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
69
+
70
+ except Exception as e:
71
+ logger.exception(
72
+ 'SQLAlchemy %s list %s #%s serialize error: %s',
73
+ type(self).__name__, self.model.__name__, pk, e,
74
+ )
75
+ msg = _('serialize_error.unexpected_error') % {'error': str(e)}
76
+ raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
77
+
69
78
  logger.debug(
70
79
  '%s model %s #%s retrieved by %s',
71
80
  type(self).__name__, self.table_schema.model.__name__, pk, user.username,
@@ -15,9 +15,12 @@ errors:
15
15
  filters_exception: 'An unknown technical error occurred while filtering data.'
16
16
  method_not_allowed: 'Error, method not allowed. This action is not permitted.'
17
17
  filter_error: 'An error occurred during filtering: {error}'
18
- serialize_field_error: 'Serialize error: %(error)s'
19
18
  bad_type_error: 'Invalid data type: %(type)s but %(expected)s expected'
20
19
 
20
+ serialize_error:
21
+ field_error: 'Field %(field_slug)s serialize error: %(error)s'
22
+ unexpected_error: 'Unexpected serialize error: %(error)s'
23
+
21
24
  search_help: 'Available search fields: %(fields)s'
22
25
  sqlalchemy_search_help: |
23
26
  <b>Available search fields:</b>
@@ -15,9 +15,12 @@ errors:
15
15
  filters_exception: 'Произошла неизвестная техническая ошибка при фильтрации данных.'
16
16
  method_not_allowed: 'Ошибка, данный метод недоступен.'
17
17
  filter_error: 'Проишла ошибка при фильтрации: %(error)s'
18
- serialize_field_error: 'Ошибка чтения данных: %(error)s'
19
18
  bad_type_error: 'Некорректный тип данных: %(type)s; ожидается %(expected)s'
20
19
 
20
+ serialize_error:
21
+ field_error: 'ошибка чтения поля %(field_slug)s: %(error)s'
22
+ unexpected_error: 'Ошибка обработки данных: %(error)s'
23
+
21
24
  search_help: 'Доступные поля для поиска: %(fields)s'
22
25
  sqlalchemy_search_help: |
23
26
  <b>Доступные поля для поиска:</b>
@@ -159,7 +159,13 @@ class FieldsSchema:
159
159
  result = {}
160
160
  for field_slug, field in self.get_fields().items():
161
161
  value = data.get(field_slug)
162
- result[field_slug] = await field.serialize(value, extra)
162
+
163
+ try:
164
+ result[field_slug] = await field.serialize(value, extra)
165
+ except FieldError as e:
166
+ e.field_slug = field_slug
167
+ raise e
168
+
163
169
  return result
164
170
 
165
171
  async def deserialize(self, data: dict, action: DeserializeAction, extra) -> dict: