Open bgreatfit opened 3 years ago
@rafalp @chimeworld @l0ud pls can you help with this error
@bgreatfit
What I found is in
Change profile_fields.get("real_name")
to profile_fields
This seems very wrong. profile_fields
is supposed to be hstore with custom profile fields and represented as dict in python.
How are you experiencing this bug?
This seems very wrong.
profile_fields
is supposed to be hstore with custom profile fields and represented as dict in python.How are you experiencing this bug?
Just launched the app on my local server after following the Readme instructions
I reproduced the same/a similar issue.
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/t/only-one-spacecraft-has-visited-distant-uranus/2/
Django Version: 3.2.15
Python Version: 3.11.1
Installed Applications:
['misago',
'misago.users',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.postgres',
'django.contrib.humanize',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ariadne_django',
'celery',
'debug_toolbar',
'mptt',
'rest_framework',
'social_django',
'misago.admin',
'misago.acl',
'misago.analytics',
'misago.cache',
'misago.core',
'misago.conf',
'misago.icons',
'misago.themes',
'misago.markup',
'misago.legal',
'misago.categories',
'misago.threads',
'misago.readtracker',
'misago.search',
'misago.oauth2',
'misago.socialauth',
'misago.graphql',
'misago.faker',
'misago.menus',
'misago.plugins']
Installed Middleware:
['debug_toolbar.middleware.DebugToolbarMiddleware',
'misago.users.middleware.RealIPMiddleware',
'misago.core.middleware.FrontendContextMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'misago.cache.middleware.cache_versions_middleware',
'misago.conf.middleware.dynamic_settings_middleware',
'misago.socialauth.middleware.socialauth_providers_middleware',
'misago.users.middleware.UserMiddleware',
'misago.acl.middleware.user_acl_middleware',
'misago.core.middleware.ExceptionHandlerMiddleware',
'misago.users.middleware.OnlineTrackerMiddleware',
'misago.admin.middleware.AdminAuthMiddleware',
'misago.threads.middleware.UnreadThreadsCountMiddleware']
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.11/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.11/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/srv/misago/misago/threads/views/thread.py", line 18, in get
frontend_context = self.get_frontend_context(request, thread, posts)
File "/srv/misago/misago/threads/views/thread.py", line 47, in get_frontend_context
"POSTS": posts.get_frontend_context(),
File "/srv/misago/misago/threads/viewmodels/posts.py", line 107, in get_frontend_context
).data
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 768, in data
ret = super().data
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 686, in to_representation
return [
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 687, in <listcomp>
self.child.to_representation(item) for item in iterable
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.11/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.11/site-packages/rest_framework/fields.py", line 1886, in to_representation
return method(value)
File "/srv/misago/misago/users/serializers/user.py", line 92, in get_real_name
return obj.get_real_name()
File "/srv/misago/misago/users/models/user.py", line 329, in get_real_name
return self.profile_fields.get("real_name")
Exception Type: AttributeError at /t/only-one-spacecraft-has-visited-distant-uranus/2/
Exception Value: 'str' object has no attribute 'get'
Steps to reproduce are:
./dev init
)docker-compose up
./dev fakedata
)127.0.0.1:8000
Will check if this also happens with by restoring/migrating a production database and by running these steps on a clean machine.
EDIT: after a second try from a clean environment this issue doesn't happen, might be related to a change I did before via admincp
or that the second time I didn't broke the fakedata
process after a shorter time.
I guess the issue is profile_fields
on user model being set to string when it should be a dict?
@jeroenbakker-atmind You mention doing a change through admin panel. Can you mention what change was that?
Good news: this doesn't seem to be a bug with Misago!
Bad news: this error occurring means that database driver didn't retrieve valid hstore extension ID from pg_type
table when initializing connection. Because it has wrong ID, it doesn't understand that profile_fields
value is from hstore field. So it returns it as string, which results in an error.
Only solution that comes to mind is moving profile_fields
from HStore to JSONB, which is standard and has constant OID in PostgreSQL (and it's clients). But then what guarantee there is that bug will not occur when data migrator is running, and profile fields are migrated to JSON as strings?
@jeroenbakker-atmind I've found a new lead for what can cause this issue. Can you please tell me what memory limits are set in your docker configuration?
I've couldn't reproduce this, but there are two possibilities now I would like to check:
OID
) for HStore extension for current connection, which results in HStore extension registering incorrectly for current DB connectionconnection_created
has been garbage collected which means its no longer registering HStore extension for new database connections.I'm unable to reproduce this, but I've added logic that will catch when this bug happens and will print error message with debug data that will help me investigate this further or let me bring this issue to Django dev team, also have a bug for this, but requested more information about it.
This error will ONLY DISPLAY IN DEBUG so production deployments and deployments with misago-docker are safe and will not display the error to the users:
I can't reproduce that in Misago 0.30. Moving from HStore to JSONB is good idea. HStoreField is only used for profile_fields
so it is only one place to change. I think that Postgres will migrate and check type correctly if migration will be done in db, not through Python libs - newer version of Postgres use hstore_to_jsonb
when value is casted to jsonb.
When I dived deeply I found that profile_fields
is not null and django put there empty string ('').
misago=# SELECT COUNT(*) FROM misago_users_user WHERE profile_fields = '';
count
-------
3141
(1 row)
After migration to JSONB, empty string was replaced with dict.
misago=# SELECT COUNT(*) FROM misago_users_user WHERE profile_fields = '{}'::jsonb;
count
-------
3141
(1 row)
misago=# SELECT profile_fields FROM misago_users_user LIMIT 1;
profile_fields
----------------
{}
(1 row)
It will be easier to find a reason with JSONField in case of any error.
I have created PR - draft, because some tests are failing
'profile_fields' has wrong type! Please post this WHOLE message on https://github.com/rafalp/Misago/issues/1352 OID: '((), ())' (valid: '((17280,), (17285,))') Receivers: '<function register_type_handlers at 0x7fe98e1adc60>' (has dead: FALSE) Repr: ''Request Method: | GET -- | -- http://0.0.0.0:8000/ 3.2.23 RuntimeError 'profile_fields' has wrong type! Please post this WHOLE message on https://github.com/rafalp/Misago/issues/1352 OID: '((), ())' (valid: '((17280,), (17285,))') Receivers: '
Thank you for reporting this! With data I've gathered so far, it seems there's a bug in Django where on rare occasions it fails to register HStore extension for database connection.
This bug resolves on itself upon docker restart and seems to only affect dev setups on localhost. Still, its annoying and I plan to move Misago away from HStore to JSON fields in one of future versions.
Related to: #1755
The errors I get when I try to log in as an admin or user Internal Server Error: /admincp/ misago_1 | Traceback (most recent call last): misago_1 | File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner misago_1 | response = get_response(request) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 106, in _get_response misago_1 | response = middleware_method(request, callback, callback_args, callback_kwargs) misago_1 | File "/srv/misago/misago/admin/middleware.py", line 17, in process_view misago_1 | return self.check_admin_authorization(request) misago_1 | File "/srv/misago/misago/admin/middleware.py", line 23, in check_admin_authorization misago_1 | return login(request) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper misago_1 | return view(request, *args, kwargs) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 142, in _wrapped_view misago_1 | response = view_func(request, *args, *kwargs) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func misago_1 | response = view_func(request, args, kwargs) misago_1 | File "/srv/misago/misago/admin/views/auth.py", line 31, in login misago_1 | return render(request, "misago/admin/login.html", {"form": form, "target": target}) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/shortcuts.py", line 36, in render misago_1 | content = loader.render_to_string(template_name, context, request, using=using) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/template/loader.py", line 62, in render_to_string misago_1 | return template.render(context, request) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render misago_1 | return self.template.render(context) misago_1 | File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 169, in render misago_1 | with context.bind_template(self): misago_1 | File "/usr/local/lib/python3.7/contextlib.py", line 112, in enter misago_1 | return next(self.gen) misago_1 | File "/usr/local/lib/python3.7/site-packages/debug_toolbar/panels/templates/panel.py", line 50, in _request_context_bind_template misago_1 | context = processor(self.request) misago_1 | File "/srv/misago/misago/users/context_processors.py", line 45, in preload_user_json misago_1 | serialized_user = serializer(request.user, context={"acl": request.user_acl}).data misago_1 | File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 563, in data misago_1 | ret = super(Serializer, self).data misago_1 | File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 262, in data misago_1 | self._data = self.to_representation(self.instance) misago_1 | File "/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py", line 530, in to_representation misago_1 | ret[field.field_name] = field.to_representation(attribute) misago_1 | File "/usr/local/lib/python3.7/site-packages/rest_framework/fields.py", line 1889, in to_representation misago_1 | return method(value) misago_1 | File "/srv/misago/misago/users/serializers/user.py", line 92, in get_real_name misago_1 | return obj.get_real_name() misago_1 | File "/srv/misago/misago/users/models/user.py", line 331, in get_real_name misago_1 | return self.profile_fields.get("real_name") misago_1 | AttributeError: 'str' object has no attribute 'get'