Skip to content

Conversation

@chrismeyersfsu
Copy link
Member

@chrismeyersfsu chrismeyersfsu commented Nov 5, 2025

  • Also begin to add detection for empty event

I'm not sure how we can get into this state (where event is empty). Best we can do for now (until we get an actual reproducer) is log when it happens and try not to include/process the malformed event so that we still return a usuable event tree.

SUMMARY
ISSUE TYPE
  • Bug, Docs Fix or other nominal change
COMPONENT NAME
  • API
ADDITIONAL INFORMATION
2025-04-30 06:43:33,600 ERROR    [73b080ed435641639659ff196e18ad1e] django.request Internal Server Error: /api/v2/jobs/4075584/job_events/children_summary/
Traceback (most recent call last):
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
   response = get_response(request)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
   response = wrapped_callback(request, *callback_args, **callback_kwargs)
 File "/usr/lib64/python3.9/contextlib.py", line 79, in inner
   return func(*args, **kwds)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
   return view_func(*args, **kwargs)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/views/generic/base.py", line 104, in view
   return self.dispatch(request, *args, **kwargs)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/api/generics.py", line 335, in dispatch
   return super(APIView, self).dispatch(request, *args, **kwargs)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
   response = self.handle_exception(exc)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
   self.raise_uncaught_exception(exc)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
   raise exc
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
   response = handler(request, *args, **kwargs)
 File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/api/views/__init__.py", line 3708, in get
   event_level_after = models.JobEvent.LEVEL_FOR_EVENT[next_non_meta_event['event']]
KeyError: '' 

Note

Handle empty/missing job event types in job_events children_summary with safe skipping and logging; add functional test coverage.

  • API (job events):
    • Skip events with missing/empty event in JobJobEventsChildrenSummary.get, logging a warning instead of erroring.
    • Treat '' as meta when scanning ahead to determine parentage for meta events; avoid KeyError and preserve tree processing.
  • Tests:
    • Add test_job_job_events_children_summary_empty_event to verify correct behavior when an event has an empty event field.

Written by Cursor Bugbot for commit 3f251e0. This will update automatically on new commits. Configure here.

@AlanCoding
Copy link
Member

  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/awx_devel/awx/api/views/__init__.py", line 3674, in get
    logging.warning(f"JobEventChildrenSummary: job event 'event' field is unexpectedly empty for job {job.id}")
    ^^^^^^^
  File "/usr/lib64/python3.11/bdb.py", line 90, in trace_dispatch
    return self.dispatch_line(frame)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/bdb.py", line 115, in dispatch_line
    if self.quitting: raise BdbQuit
                      ^^^^^^^^^^^^^
bdb.BdbQuit

from test failure, not the same as your expectation?

@chrismeyersfsu
Copy link
Member Author

chrismeyersfsu commented Nov 6, 2025

Accidentally left a breakpoint() in the code.

Think of this PR as pseudo code. My point was to show creating an event with event='' recreates the reported error.

@AlanCoding
Copy link
Member

Now it gives this which is intended:

  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/_pytest/python.py", line 157, in pytest_pyfunc_call
    result = testfunction(**testargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/awx_devel/awx/main/tests/functional/api/test_events.py", line 173, in test_job_job_events_children_summary_empty_event
    response = get(url, user=objs.superusers.admin, expect=200)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/awx_devel/awx/main/tests/functional/conftest.py", line 631, in rf
    response = view(request, *view_args, **view_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
    return view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/awx_devel/awx/api/generics.py", line 375, in dispatch
    return super(APIView, self).dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/var/lib/awx/venv/awx/lib64/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/awx_devel/awx/api/views/__init__.py", line 3638, in get
    level = models.JobEvent.LEVEL_FOR_EVENT[e['event']]
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: ''

@AlanCoding AlanCoding changed the title Add test to recreate jobs/4075584/job_events/children_summary/ error AAP-45541 Add test to recreate jobs/4075584/job_events/children_summary/ error Nov 7, 2025
@pb82 pb82 marked this pull request as ready for review December 17, 2025 12:47
).save()
JobEvent.create_from_data(job_id=job.pk, uuid='uuid4', parent_uuid='', event='verbose', counter=4, stdout='a' * 1024, job_created=job.created).save()

JobEvent.create_from_data(job_id=job.pk, uuid='uuid4', parent_uuid='', event='', counter=5, stdout='a' * 1024, job_created=job.created).save()
Copy link

Choose a reason for hiding this comment

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

Bug: Duplicate uuid in test creates incorrect data mapping

The empty event at line 163 uses uuid='uuid4', which duplicates the uuid from the verbose event at line 161. In the existing test patterns, each event has a unique uuid. This causes the map_uuid_counter dictionary to map uuid4 to counter 5 (empty event) instead of counter 4 (verbose event), since the later event overwrites the earlier one. While this doesn't break the current test (no event uses parent_uuid='uuid4'), it creates inconsistent test data that could mask bugs or cause failures if the test is extended.

Fix in Cursor Fix in Web

@sonarqubecloud
Copy link

for i, e in enumerate(events):
if not e['event']:
logging.warning(f'event type missing for event {e}')
continue
Copy link
Member

Choose a reason for hiding this comment

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

I think my only remaining question is if this continue is necessary or if we could just handle these events within the rest of the logic. But either way.

@pb82 pb82 merged commit 41f1ffc into ansible:devel Dec 17, 2025
22 checks passed
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.

3 participants