Handle UniqueConstraint errors while saving coursebook #338

Closed
opened 2024-11-28 14:03:38 +01:00 by hansegucker · 4 comments
Owner

Currently, the content isn't saved.

Traceback (most recent call last):
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 948, in get_or_create
return self.get(**kwargs), False
^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 649, in get
raise self.model.DoesNotExist(
^

During handling of the above exception (Documentation matching query does not exist.), another exception occurred:
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django_prometheus/db/common.py", line 69, in execute
return super().execute(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
raise ex.with_traceback(None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The above exception (doppelter Schlüsselwert verletzt Unique-Constraint »unique_calendar_event_per_amends_and_datetimes«
DETAIL: Schlüssel »(datetime_start, datetime_end, amends_id)=(2024-11-27 09:35:00+00, 2024-11-27 10:20:00+00, 3639676)« existiert bereits.) was the direct cause of the following exception:
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/integrations/django/views.py", line 94, in sentry_wrapped_callback
return callback(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/views/generic/base.py", line 104, in view
return self.dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 191, in dispatch
responses = [self.get_response(request, entry) for entry in data]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 191, in <listcomp>
responses = [self.get_response(request, entry) for entry in data]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 218, in get_response
execution_result = self.execute_graphql_request(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/views.py", line 1278, in execute_graphql_request
raise error
^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphql/execution/execute.py", line 523, in execute_field
result = resolve_fn(source, info, **args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 182, in mutate
objs = [cls.create_or_update(info, doc) for doc in input]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 182, in <listcomp>
objs = [cls.create_or_update(info, doc) for doc in input]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 160, in create_or_update
obj, __ = Documentation.get_or_create_by_id(_id, info.context.user)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/models.py", line 322, in get_or_create_by_id
return cls.create_from_lesson_event(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/models.py", line 305, in create_from_lesson_event
obj, __ = cls.objects.get_or_create(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 955, in get_or_create
return self.create(**params), True
^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 679, in create
obj.save(force_insert=True, using=self.db)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/models.py", line 1661, in save
super().save(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/mixins.py", line 156, in save
super().save(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/polymorphic/models.py", line 87, in save
return super().save(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 891, in save
self.save_base(
^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 994, in save_base
parent_inserted = self._save_parents(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1047, in _save_parents
updated = self._save_table(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1160, in _save_table
results = self._do_insert(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1201, in _do_insert
return manager._insert(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 1847, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1836, in execute_sql
cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/utils.py", line 1788, in runner
return sentry_patched_function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/integrations/django/__init__.py", line 653, in execute
result = real_execute(self, sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
return self._execute_with_wrappers(

File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
with self.db.wrap_database_errors:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django_prometheus/db/common.py", line 69, in execute
return super().execute(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/srv/aleksis/envs/production/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute
raise ex.with_traceback(None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: GraphQLError at /graphql/
Exception Value: doppelter Schlüsselwert verletzt Unique-Constraint »unique_calendar_event_per_amends_and_datetimes«
DETAIL: Schlüssel »(datetime_start, datetime_end, amends_id)=(2024-11-27 09:35:00+00, 2024-11-27 10:20:00+00, 3639676)« existiert bereits.

GraphQL request:2:3
1 | mutation createOrUpdateDocumentations($input: [DocumentationInputType]!) {
2 | createOrUpdateDocumentations(input: $input) {
| ^
3 | items: documentations {
Currently, the content isn't saved. ``` Traceback (most recent call last): File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 948, in get_or_create return self.get(**kwargs), False ^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 649, in get raise self.model.DoesNotExist( ^ During handling of the above exception (Documentation matching query does not exist.), another exception occurred: File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute return self.cursor.execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django_prometheus/db/common.py", line 69, in execute return super().execute(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute raise ex.with_traceback(None) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The above exception (doppelter Schlüsselwert verletzt Unique-Constraint »unique_calendar_event_per_amends_and_datetimes« DETAIL: Schlüssel »(datetime_start, datetime_end, amends_id)=(2024-11-27 09:35:00+00, 2024-11-27 10:20:00+00, 3639676)« existiert bereits.) was the direct cause of the following exception: File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/integrations/django/views.py", line 94, in sentry_wrapped_callback return callback(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/views/generic/base.py", line 104, in view return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 48, in _wrapper return bound_method(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 188, in _view_wrapper result = _process_exception(request, e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/utils/decorators.py", line 186, in _view_wrapper response = view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 191, in dispatch responses = [self.get_response(request, entry) for entry in data] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 191, in <listcomp> responses = [self.get_response(request, entry) for entry in data] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphene_django/views.py", line 218, in get_response execution_result = self.execute_graphql_request( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/views.py", line 1278, in execute_graphql_request raise error ^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/graphql/execution/execute.py", line 523, in execute_field result = resolve_fn(source, info, **args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 182, in mutate objs = [cls.create_or_update(info, doc) for doc in input] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 182, in <listcomp> objs = [cls.create_or_update(info, doc) for doc in input] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/schema/documentation.py", line 160, in create_or_update obj, __ = Documentation.get_or_create_by_id(_id, info.context.user) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/models.py", line 322, in get_or_create_by_id return cls.create_from_lesson_event( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/apps/alsijil/models.py", line 305, in create_from_lesson_event obj, __ = cls.objects.get_or_create( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 955, in get_or_create return self.create(**params), True ^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 679, in create obj.save(force_insert=True, using=self.db) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/models.py", line 1661, in save super().save(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/aleksis/core/mixins.py", line 156, in save super().save(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/polymorphic/models.py", line 87, in save return super().save(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 891, in save self.save_base( ^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 994, in save_base parent_inserted = self._save_parents( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1047, in _save_parents updated = self._save_table( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1160, in _save_table results = self._do_insert( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/base.py", line 1201, in _do_insert return manager._insert( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/query.py", line 1847, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1836, in execute_sql cursor.execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/utils.py", line 1788, in runner return sentry_patched_function(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/sentry_sdk/integrations/django/__init__.py", line 653, in execute result = real_execute(self, sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute return self._execute_with_wrappers( File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers return executor(sql, params, many, context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute with self.db.wrap_database_errors: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute return self.cursor.execute(sql, params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/django_prometheus/db/common.py", line 69, in execute return super().execute(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/aleksis/envs/production/lib/python3.11/site-packages/psycopg/cursor.py", line 97, in execute raise ex.with_traceback(None) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exception Type: GraphQLError at /graphql/ Exception Value: doppelter Schlüsselwert verletzt Unique-Constraint »unique_calendar_event_per_amends_and_datetimes« DETAIL: Schlüssel »(datetime_start, datetime_end, amends_id)=(2024-11-27 09:35:00+00, 2024-11-27 10:20:00+00, 3639676)« existiert bereits. GraphQL request:2:3 1 | mutation createOrUpdateDocumentations($input: [DocumentationInputType]!) { 2 | createOrUpdateDocumentations(input: $input) { | ^ 3 | items: documentations { ```
Author
Owner

assigned to @hansegucker

assigned to @hansegucker
Author
Owner

created branch 338-handle-uniqueconstraint-errors-while-saving-coursebook to address this issue

created branch [`338-handle-uniqueconstraint-errors-while-saving-coursebook`](/AlekSIS/official/AlekSIS-App-Alsijil/-/compare/master...338-handle-uniqueconstraint-errors-while-saving-coursebook) to address this issue
Author
Owner

mentioned in merge request !832

mentioned in merge request !832
Author
Owner

mentioned in commit 77ea567285

mentioned in commit 77ea567285cacc05e41d694efc1703fc6588cd3a
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
aleksis/AlekSIS-App-Alsijil#338
No description provided.