)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"raise_forever on wsgi app init"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add a raise_forever decorator which"},{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"5d2affdf_6ba005bf","line":9,"range":{"start_line":9,"start_character":12,"end_line":9,"end_character":15},"updated":"2025-03-20 14:23:16.000000000","message":"\"adds\"","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"raise_forever on wsgi app init"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add a raise_forever decorator which"},{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"1db6bd84_41007037","line":9,"range":{"start_line":9,"start_character":12,"end_line":9,"end_character":15},"in_reply_to":"5d2affdf_6ba005bf","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":7,"context_line":"raise_forever on wsgi app init"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add a raise_forever decorator which"},{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"da72530c_81ba7dec","line":10,"range":{"start_line":10,"start_character":18,"end_line":10,"end_character":34},"updated":"2025-03-20 14:23:16.000000000","message":"\"init_application function\"","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":7,"context_line":"raise_forever on wsgi app init"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change add a raise_forever decorator which"},{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"b3e144d9_f14363bd","line":10,"range":{"start_line":10,"start_character":18,"end_line":10,"end_character":34},"in_reply_to":"da72530c_81ba7dec","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"},{"line_number":14,"context_line":"and cause future invocations of the function to always"},{"line_number":15,"context_line":"return that same excpetion forever."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"2f504363_d6bd8b88","line":13,"range":{"start_line":13,"start_character":40,"end_line":13,"end_character":49},"updated":"2025-03-20 14:23:16.000000000","message":"\"exceptions\"","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":10,"context_line":"is applied to the init_applciation funciton in our"},{"line_number":11,"context_line":"common wsgi_app module."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"},{"line_number":14,"context_line":"and cause future invocations of the function to always"},{"line_number":15,"context_line":"return that same excpetion forever."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"6d972e34_a6ef3b29","line":13,"range":{"start_line":13,"start_character":40,"end_line":13,"end_character":49},"in_reply_to":"2f504363_d6bd8b88","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"},{"line_number":14,"context_line":"and cause future invocations of the function to always"},{"line_number":15,"context_line":"return that same excpetion forever."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Currently unrecoverable is defined as any oslo.config error"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"291a016c_abd71ddf","line":15,"range":{"start_line":15,"start_character":17,"end_line":15,"end_character":26},"updated":"2025-03-20 14:23:16.000000000","message":"\"exception\"","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This decorator will catch unrecoverable excptions"},{"line_number":14,"context_line":"and cause future invocations of the function to always"},{"line_number":15,"context_line":"return that same excpetion forever."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Currently unrecoverable is defined as any oslo.config error"},{"line_number":18,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7779bf9c_405f52fa","line":15,"range":{"start_line":15,"start_character":17,"end_line":15,"end_character":26},"in_reply_to":"291a016c_abd71ddf","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"2ff39077b9464710ac25fadf2cf943f44a9ae448","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"6421c133_8c68fc5b","updated":"2025-03-20 11:02:33.000000000","message":"here are the logs testing this with apache\n\nhttps://logserver.rdoproject.org/43/943/edfb00528517affeaa38d3a0a4d6a9e34da7b56f/github-check/nova-operator-tempest-multinode/6d7cb4f/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/logs/nova-api-log-previous.log\n\nhttps://logserver.rdoproject.org/43/943/edfb00528517affeaa38d3a0a4d6a9e34da7b56f/github-check/nova-operator-tempest-multinode/6d7cb4f/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/logs/nova-api-api.log\n\nas we can see in both the service and apache log we very clearly see the 500s and the repeated config excptions present.\n\nthe error in this case is\n\noslo_config.cfg.ConfigFileValueError: Value for option osapi_compute_workers from LocationInfo(location\u003d\u003cLocations.user: (4, True)\u003e, detail\u003d\u0027/etc/nova/nova.conf.d/01-nova.conf\u0027) is not valid: Should be greater than or equal to 1\n\ni set it to 0 in the job\nhttps://github.com/openstack-k8s-operators/nova-operator/pull/943/files\n\n\nim gong to be conservitive and im going to find the parent of oslo_config.cfg.ConfigFileValueError and only catch that unless its ValueError or Execption\n\n\nhardfailing on un recoverable errors like config error makes sense but i dont want to acidentaly fail on trainsitent errorrs\n\nwe can alwasy extend the list later if requried.","commit_id":"55edab789be72567eb9496f6d9badeec5fbbbeaa"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"011daaec_9dd2b227","updated":"2025-03-20 14:23:16.000000000","message":"I know Bogdan is going to say something about arguing here, but I still think this is the right approach. We just need to decide if we latch by default or not.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"f199e1cfe615dbef1027a8eec71418411ed91443","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"47ebc7b9_75068058","in_reply_to":"011daaec_9dd2b227","updated":"2025-03-20 14:42:12.000000000","message":"By latching, do you mean raising an exception? Doing it for only config errors for the beginning makes sense to me. Brining here that metaphor, where we consider Apache web server as a door guard which doesn\u0027t let our WSGI application out, we should avoid \u0027arguing\u0027 with it, which is trying to list all possible soft-failure scenarios that we consider no applicable for the \"latching\". Instead we should behave simple and clearly state what failure cases we consider fatal, which I believe this revision of the patch exactly does by pointing out as a such only config errors","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"99518db4353fb8cde2cf4497b85eabf120fe8aee","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"e6f49d82_87ccfb19","in_reply_to":"47ebc7b9_75068058","updated":"2025-03-20 14:56:57.000000000","message":"\u003e By latching, do you mean raising an exception?\n\nBy \"latching\" I mean in the \"security system\" sense of the word. Meaning, once we\u0027ve decided that something is wrong, we \"latch\" in error state and don\u0027t return to normal.\n\n\u003e Doing it for only config errors for the beginning makes sense to me. Brining here that metaphor, where we consider Apache web server as a door guard which doesn\u0027t let our WSGI application out, we should avoid \u0027arguing\u0027 with it, which is trying to list all possible soft-failure scenarios that we consider no applicable for the \"latching\". Instead we should behave simple and clearly state what failure cases we consider fatal, which I believe this revision of the patch exactly does by pointing out as a such only config errors\n\nEverything you said here makes sense, I just disagree with the conclusion that keeping it simple means catching specifically-fatal errors instead of assuming everything is fatal unless we know it\u0027s not. Your argument of \"not trying to list all possible soft-failure scenarios\" is exactly why I want the default to be to latch into error state.\n\nThis is not the request pipeline, this is the \"initialize your application\" pipeline. That should never ever fail unless something is very wrong. We might talk to the DB in that path to create a service record (not even sure) but we shouldn\u0027t be talking to MQ, external services, etc. If something raises in the \"initialize yourself\" part of the application, the likelihood that we didn\u0027t finish enough setup to be useful is *high*.\n\nLet\u0027s consider what is going to happen if we\u0027re latched in error state. Probably the tool starting us will kill and restart us a number of times before marking us as really failed, setting off an alarm, and not putting us into the load balancer, possibly trying to schedule us somewhere else. In the case where we have a false positive (i.e. we latch in error state for some actually-retryable exception) then the container/pod management\u0027s restart will fix us. If, however, we\u0027re failing for some legit non-retryable reason but we don\u0027t know about it, so we don\u0027t latch into error state... we just break. We get put into the load balancer and bad things happen, but we say \"meh, `ValueError` seemed fine to me!\"\n\nLet me restate something from above again, which I think pretty well summarizes the argument here:\n\n\u003e If something raises in the \"initialize yourself\" part of the application, the likelihood that we didn\u0027t finish enough setup to be useful is *high*.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"353cc51b400d4dd0bc15e4517da39436d635d3bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"58b6d62e_bb625299","in_reply_to":"4bb12107_1e668e87","updated":"2025-03-21 11:45:45.000000000","message":"As \"missing out latching on a false positive\" I meant something like forgetting to add a newly indtroduced DB-related exception to this \"allow list\"","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"07f12e25122c97ceebdb41f06a3ddb904d7cd3fb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"4bb12107_1e668e87","in_reply_to":"e6f49d82_87ccfb19","updated":"2025-03-21 11:41:21.000000000","message":"\u003e In the case where we have a false positive (i.e. we latch in error state for some actually-retryable exception) then the container/pod management\u0027s restart will fix us. If, however, we\u0027re failing for some legit non-retryable reason but we don\u0027t know about it, so we don\u0027t latch into error state... we just break\n\nThank you for explaining. As you explained now, I got that missing out latching on a false positive would be less destructive than failing blindly. That surely means we should revert the logic then :)","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8e89d50b_0da917c1","updated":"2025-03-21 13:59:52.000000000","message":"Sean, were you still going to make another rev of the code or no?","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"ebe70dcb9e35e6e5c529be9c90d60b0375356ddb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"52247dd7_3167c661","updated":"2025-03-20 19:37:59.000000000","message":"and just for prosperity \n\nthe operator job failed with the expected excption when deployed with a broken config\n\nhttps://softwarefactory-project.io/zuul/t/rdoproject.org/build/2107925e782548ad99a93e085ae1e6ff/log/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/logs/nova-api-api-previous.log#85","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5eab3143a2e3078f08b9b68825ff33bca4172def","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"ed9994e1_b52d2027","in_reply_to":"8e89d50b_0da917c1","updated":"2025-03-21 14:33:18.000000000","message":"yes so i can incoperate any of the remaining commetns in that too","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"f109dc3b_32c8fa2e","updated":"2025-03-21 15:38:45.000000000","message":"Looks good to me otherwise :)","commit_id":"6e0cdd386cfa3e77983e366002630def4ecbcd2d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d7a0810ffdddcfed61e7edd24e4cc385c76d5d8a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f80792be_6d9ee9c7","updated":"2025-03-21 15:46:29.000000000","message":"Thanks!","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"3564a5cc925bd236f3e03a80ca06ed548248c326","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"58ad9f93_dfe6b4d3","updated":"2025-03-24 13:34:28.000000000","message":"nyway,","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"6ebdfdb0_b3f60a59","updated":"2025-03-24 23:17:24.000000000","message":"Just some typos, with `class _SentinelExcpetion` being the big one.","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"790b3536ea18dbbf582226fe7d337dd6c7d89568","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"bb9012f9_6d0c2aec","updated":"2025-03-22 00:05:37.000000000","message":"nova log\n\nhttps://logserver.rdoproject.org/43/943/edfb00528517affeaa38d3a0a4d6a9e34da7b56f/github-check/nova-operator-tempest-multinode/795bdc9/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/logs/nova-api-log.log\n\napache\nhttps://logserver.rdoproject.org/43/943/edfb00528517affeaa38d3a0a4d6a9e34da7b56f/github-check/nova-operator-tempest-multinode/795bdc9/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/logs/nova-api-api.log\n\nas we can see the logging still works and the excption is raised as expected.\n\nif we look at the descirbe form k8s\n\nhttps://logserver.rdoproject.org/43/943/edfb00528517affeaa38d3a0a4d6a9e34da7b56f/github-check/nova-operator-tempest-multinode/795bdc9/controller/ci-framework-data/logs/openstack-k8s-operators-openstack-must-gather/namespaces/openstack/pods/nova-api-0/nova-api-0-describe\n\n\nwe can see the ready condtion is false \n\n```\nConditions:\n  Type                        Status\n  PodReadyToStartContainers   True \n  Initialized                 True \n  Ready                       False \n  ContainersReady             False \n  PodScheduled                True \n```\n\nwe can also see the failure are reporpted properly\n\n```\n    State:          Waiting\n      Reason:       CrashLoopBackOff\n    Last State:     Terminated\n      Reason:       Completed\n      Exit Code:    0\n      Started:      Fri, 21 Mar 2025 22:46:48 +0000\n      Finished:     Fri, 21 Mar 2025 22:47:47 +0000\n    Ready:          False\n    Restart Count:  11\n    Liveness:       http-get http://:8774/ delay\u003d0s timeout\u003d30s period\u003d30s #success\u003d1 #failure\u003d3\n    Readiness:      http-get http://:8774/ delay\u003d0s timeout\u003d30s period\u003d30s #success\u003d1 #failure\u003d3\n    Startup:        http-get http://:8774/ delay\u003d0s timeout\u003d1s period\u003d10s #success\u003d1 #failure\u003d6\n```\n\n\n```\n  Normal   Started         31m                 kubelet            Started container nova-api-log\n  Warning  Unhealthy       30m                 kubelet            Startup probe failed: Get \"http://10.217.0.191:8774/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n  Warning  Unhealthy       30m                 kubelet            Startup probe failed: Get \"http://10.217.0.191:8774/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)\n  Normal   Killing         30m                 kubelet            Container nova-api-api failed startup probe, will be restarted\n  Warning  Unhealthy       30m (x5 over 30m)   kubelet            Startup probe failed: HTTP probe failed with statuscode: 500\n```\n\nwhich is exactly what should happen when the config is broken\n\n\nhttps://github.com/openstack-k8s-operators/nova-operator/pull/943/commits/edfb00528517affeaa38d3a0a4d6a9e34da7b56f","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a0d629ada753572a8c5dc8935ed3da401aeb11c2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"d303ea42_e151ddb0","updated":"2025-03-24 23:40:07.000000000","message":"Looks OK to me. Dan and Bogdan were +2/+1 previously and this just fixed some typos, so going ahead and approving.","commit_id":"8dcbbe43e71b1528777fd5a905ad340e916d94ac"}],"nova/api/openstack/wsgi_app.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"6990a47b_ffa5ba1c","line":119,"updated":"2025-03-20 14:23:16.000000000","message":"I would name this something else, personally. This doesn\u0027t really convey the \"raise forever, if raised ever\" sort of latching behavior you\u0027re going for. I\u0027ll think about an alternative to suggest.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e50c5f3c7dc790db5dff921ed342cc7545319af4","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"94cd37ef_33da3375","line":119,"in_reply_to":"2835166d_1f98e4fc","updated":"2025-03-20 16:16:48.000000000","message":"What about ` @utils.raise_henceforth`? I got it from the thesaurus 🙂","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"ccf745c215e5021ae67fe2929693bb9646f1a299","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"6641c679_f3537126","line":119,"in_reply_to":"2bd1b808_7865e247","updated":"2025-03-20 19:00:15.000000000","message":"Yeah. I get what it means but \"latch\" seems like an unusual word to use that doesn\u0027t seem familiar in Nova or other projects. In equivalent terms I would think to use the word \"pin\" or \"lock\" instead of \"latch\". Just MHO.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77201f84d3f22c65ac7a7acb3a4d8771f6888c61","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"2bd1b808_7865e247","line":119,"in_reply_to":"650286b6_12dea686","updated":"2025-03-20 18:29:01.000000000","message":"\"latch error on raise\" makes sense to me. Doesn\u0027t sound as fancy as \"henceforth\" but I think it\u0027s more meaningful :)","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7016c2e304903040a98fe1e376249f49bcadd04c","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"cd5cb7e1_0da44229","line":119,"in_reply_to":"6641c679_f3537126","updated":"2025-03-20 19:04:03.000000000","message":"A \"latching relay\" is what I\u0027m thinking of, which is a relay that keeps its state without being energized. Also, \"latching circuits\" in security systems are those that can\u0027t be turned off. Once you set off the alarm, there\u0027s no way to stop it. Like the panic button in a bank - the robber can\u0027t go press it again to cancel.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"7fc27d9ada140e064566e94b9b9745b9f6ce5fb1","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"2835166d_1f98e4fc","line":119,"in_reply_to":"6990a47b_ffa5ba1c","updated":"2025-03-20 15:07:41.000000000","message":"sure i can rename it i was going\nto to make it more generic orgianlly and take the set of ecpttion to catch but honestly i didnt see where we would reuse this so ketp it simpel\n\nso whatever name you come up with let me know.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"650286b6_12dea686","line":119,"in_reply_to":"94cd37ef_33da3375","updated":"2025-03-20 18:21:39.000000000","message":"i went with @utils.latch_error_on_raise()\nand yes the `()` are need otherwise it changes the behvior.....\nthat totally didnt take a freaking hour and a half to figure out.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":false,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"f4dddbb6_80c51569","line":119,"in_reply_to":"b74f1e9a_572b82f1","updated":"2025-03-21 13:59:52.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c45388580c286b98695e41866e3f2c5c4c6540e5","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"b74f1e9a_572b82f1","line":119,"in_reply_to":"be90b36a_663f6a5f","updated":"2025-03-20 20:14:33.000000000","message":"Yep, exactly.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a55a573f155ed2d70bba14c2c03809fb237dc662","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"ba506b11_7624d1d7","line":119,"in_reply_to":"cd5cb7e1_0da44229","updated":"2025-03-20 19:23:23.000000000","message":"I see, TIL.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"dd8e1c5cf53b5306bd722e1388d6f75eaa4f0c78","unresolved":true,"context_lines":[{"line_number":116,"context_line":"            logging.DEBUG)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"@utils.raise_forever"},{"line_number":120,"context_line":"def init_application(name):"},{"line_number":121,"context_line":"    conf_files \u003d _get_config_files()"},{"line_number":122,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"be90b36a_663f6a5f","line":119,"in_reply_to":"cd5cb7e1_0da44229","updated":"2025-03-20 19:35:33.000000000","message":"i basically implemnted an RS nor latch in the decorator\n\nits set by the excption being raised and reset with the reset funciton.\n\nso i get where dan was coming form but mainly because i have built those in factorio and minecraft when automating things. i.e. to debounce a circut by addign some hysteresis between a set point and a reset point.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"}],"nova/tests/unit/api/openstack/test_wsgi_app.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"4f25410408d0c9564c6b7dcbc288d58cb65a2246","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        self.assertIs(first_err, second_err)"},{"line_number":90,"context_line":"        self.assertNotIn("},{"line_number":91,"context_line":"            \u0027Global data already initialized, not re-initializing.\u0027,"},{"line_number":92,"context_line":"            self.stdlog.logger.output)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":95,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"6fd2d31b_e89c611d","line":92,"updated":"2025-03-19 17:05:49.000000000","message":"this should not be requied if i filter our db errors although i will need to update form test.TestingException in the mocks.","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a595a652a18a8e09abbb3894e7e7bcfde8bca9ce","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        self.assertIs(first_err, second_err)"},{"line_number":90,"context_line":"        self.assertNotIn("},{"line_number":91,"context_line":"            \u0027Global data already initialized, not re-initializing.\u0027,"},{"line_number":92,"context_line":"            self.stdlog.logger.output)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":95,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"b6cff41a_12093ba2","line":92,"in_reply_to":"6fd2d31b_e89c611d","updated":"2025-03-20 14:04:16.000000000","message":"Done","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":95,"context_line":"    @mock.patch(\u0027nova.api.openstack.wsgi_app._get_config_files\u0027)"},{"line_number":96,"context_line":"    def test_init_application_called_unrecoverable("},{"line_number":97,"context_line":"        self, mock_get_files,"},{"line_number":98,"context_line":"    ):"},{"line_number":99,"context_line":"        \"\"\"Test that init_application can tolerate being called more then once"},{"line_number":100,"context_line":"        in a single python interpreter instance and raises the same exception"},{"line_number":101,"context_line":"        forever if its unrecoverable."}],"source_content_type":"text/x-python","patch_set":3,"id":"51e3fca4_f8d1ee9c","line":98,"updated":"2025-03-20 14:23:16.000000000","message":"Could be one line instead of three, like the one below it? I thought even in the new ugly syntax rules such was allowed if it fit?","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"7fc27d9ada140e064566e94b9b9745b9f6ce5fb1","unresolved":true,"context_lines":[{"line_number":95,"context_line":"    @mock.patch(\u0027nova.api.openstack.wsgi_app._get_config_files\u0027)"},{"line_number":96,"context_line":"    def test_init_application_called_unrecoverable("},{"line_number":97,"context_line":"        self, mock_get_files,"},{"line_number":98,"context_line":"    ):"},{"line_number":99,"context_line":"        \"\"\"Test that init_application can tolerate being called more then once"},{"line_number":100,"context_line":"        in a single python interpreter instance and raises the same exception"},{"line_number":101,"context_line":"        forever if its unrecoverable."}],"source_content_type":"text/x-python","patch_set":3,"id":"b70519d1_e362b3fe","line":98,"in_reply_to":"51e3fca4_f8d1ee9c","updated":"2025-03-20 15:07:41.000000000","message":"ya this was just a copy paste of \n\n```\n    def test_init_application_called_twice(\n        self, mock_get_files, mock_setup, mock_main_db_configure,\n        mock_api_db_configure, mock_argv,\n    ):\n```\n\nabove with the extra stuff dropped.\nill do that when I fix the typos","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    @mock.patch(\u0027nova.api.openstack.wsgi_app._get_config_files\u0027)"},{"line_number":96,"context_line":"    def test_init_application_called_unrecoverable("},{"line_number":97,"context_line":"        self, mock_get_files,"},{"line_number":98,"context_line":"    ):"},{"line_number":99,"context_line":"        \"\"\"Test that init_application can tolerate being called more then once"},{"line_number":100,"context_line":"        in a single python interpreter instance and raises the same exception"},{"line_number":101,"context_line":"        forever if its unrecoverable."}],"source_content_type":"text/x-python","patch_set":3,"id":"b2f27c47_2115f593","line":98,"in_reply_to":"b70519d1_e362b3fe","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        for i in range(5):"},{"line_number":107,"context_line":"            e \u003d self.assertRaises("},{"line_number":108,"context_line":"                excepted_type, wsgi_app.init_application, \u0027nova-api\u0027)"},{"line_number":109,"context_line":"            self.assertIs(e, error)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":112,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"d371bbd6_5d0d0e71","line":109,"updated":"2025-03-20 14:23:16.000000000","message":"So, if I uncomment your new decorator add, this test still passes for me. I think you need some way to make the second invocation actually break if the latch is thrown.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"7fc27d9ada140e064566e94b9b9745b9f6ce5fb1","unresolved":true,"context_lines":[{"line_number":106,"context_line":"        for i in range(5):"},{"line_number":107,"context_line":"            e \u003d self.assertRaises("},{"line_number":108,"context_line":"                excepted_type, wsgi_app.init_application, \u0027nova-api\u0027)"},{"line_number":109,"context_line":"            self.assertIs(e, error)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":112,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"f50bb09b_e56b7d13","line":109,"in_reply_to":"d371bbd6_5d0d0e71","updated":"2025-03-20 15:07:41.000000000","message":"oh i can just make the side effect be a list i think.\n\nill have it raise \n\n mock_get_files.side_effect \u003d [error, test.TestingException,, test.TestingException, , test.TestingException, , test.TestingException]\n \n or something like that.\n it should alwasy return error and never  test.TestingException with my change and it would change without it.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        for i in range(5):"},{"line_number":107,"context_line":"            e \u003d self.assertRaises("},{"line_number":108,"context_line":"                excepted_type, wsgi_app.init_application, \u0027nova-api\u0027)"},{"line_number":109,"context_line":"            self.assertIs(e, error)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":112,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"70f74d94_c491eeff","line":109,"in_reply_to":"f50bb09b_e56b7d13","updated":"2025-03-20 18:21:39.000000000","message":"Done","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6b02bab46009a5e62038ab7287615567e304a072","unresolved":true,"context_lines":[{"line_number":82,"context_line":"        # raised during it."},{"line_number":83,"context_line":"        self.assertRaises(test.TestingException, wsgi_app.init_application,"},{"line_number":84,"context_line":"                          \u0027nova-api\u0027)"},{"line_number":85,"context_line":"        # reset the raise_forever decorator"},{"line_number":86,"context_line":"        wsgi_app.init_application.reset()"},{"line_number":87,"context_line":"        # Now run init_application a second time, it should succeed since no"},{"line_number":88,"context_line":"        # exception is being raised (the init of global data should not be"}],"source_content_type":"text/x-python","patch_set":6,"id":"943a4f7e_7bad6a0b","line":85,"range":{"start_line":85,"start_character":20,"end_line":85,"end_character":33},"updated":"2025-03-21 20:51:44.000000000","message":"i guess i should fix this.","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"88b2aca40f46f832e2e765a6edac8f51e0b3bed4","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        # raised during it."},{"line_number":83,"context_line":"        self.assertRaises(test.TestingException, wsgi_app.init_application,"},{"line_number":84,"context_line":"                          \u0027nova-api\u0027)"},{"line_number":85,"context_line":"        # reset the raise_forever decorator"},{"line_number":86,"context_line":"        wsgi_app.init_application.reset()"},{"line_number":87,"context_line":"        # Now run init_application a second time, it should succeed since no"},{"line_number":88,"context_line":"        # exception is being raised (the init of global data should not be"}],"source_content_type":"text/x-python","patch_set":6,"id":"8afec04a_495cfbbd","line":85,"range":{"start_line":85,"start_character":20,"end_line":85,"end_character":33},"in_reply_to":"943a4f7e_7bad6a0b","updated":"2025-03-21 20:53:31.000000000","message":"Done","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6b02bab46009a5e62038ab7287615567e304a072","unresolved":true,"context_lines":[{"line_number":107,"context_line":"            e \u003d self.assertRaises("},{"line_number":108,"context_line":"                excepted_type, wsgi_app.init_application, \u0027nova-api\u0027)"},{"line_number":109,"context_line":"            self.assertIs(e, error)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":112,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"},{"line_number":113,"context_line":"    def test_setup_service_version_workaround(self, mock_check_old, mock_get):"}],"source_content_type":"text/x-python","patch_set":6,"id":"4777080d_8d6ff114","line":110,"updated":"2025-03-21 20:51:44.000000000","message":"if we really want to assert that the underlying funciton is not called multiple times i can do it here\n```\nmock_get_files.assert_called_once()\n```\n\nbut im not sure that is really required","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"88b2aca40f46f832e2e765a6edac8f51e0b3bed4","unresolved":false,"context_lines":[{"line_number":107,"context_line":"            e \u003d self.assertRaises("},{"line_number":108,"context_line":"                excepted_type, wsgi_app.init_application, \u0027nova-api\u0027)"},{"line_number":109,"context_line":"            self.assertIs(e, error)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    @mock.patch(\u0027nova.objects.Service.get_by_host_and_binary\u0027)"},{"line_number":112,"context_line":"    @mock.patch(\u0027nova.utils.raise_if_old_compute\u0027)"},{"line_number":113,"context_line":"    def test_setup_service_version_workaround(self, mock_check_old, mock_get):"}],"source_content_type":"text/x-python","patch_set":6,"id":"0b8d982b_3b337785","line":110,"in_reply_to":"4777080d_8d6ff114","updated":"2025-03-21 20:53:31.000000000","message":"Done","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":true,"context_lines":[{"line_number":95,"context_line":"        \u0027sys.argv\u0027, new\u003dmock.MagicMock(return_value\u003dmock.sentinel.argv))"},{"line_number":96,"context_line":"    @mock.patch(\u0027nova.api.openstack.wsgi_app._get_config_files\u0027)"},{"line_number":97,"context_line":"    def test_init_application_called_unrecoverable(self, mock_get_files):"},{"line_number":98,"context_line":"        \"\"\"Test that init_application can tolerate being called more then once"},{"line_number":99,"context_line":"        in a single python interpreter instance and raises the same exception"},{"line_number":100,"context_line":"        forever if its unrecoverable."},{"line_number":101,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"62bb88ea_66ae0b47","line":98,"range":{"start_line":98,"start_character":69,"end_line":98,"end_character":73},"updated":"2025-03-24 23:17:24.000000000","message":"than","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e1e0308487428d257f4a201542d7588f5d7dd143","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \u0027sys.argv\u0027, new\u003dmock.MagicMock(return_value\u003dmock.sentinel.argv))"},{"line_number":96,"context_line":"    @mock.patch(\u0027nova.api.openstack.wsgi_app._get_config_files\u0027)"},{"line_number":97,"context_line":"    def test_init_application_called_unrecoverable(self, mock_get_files):"},{"line_number":98,"context_line":"        \"\"\"Test that init_application can tolerate being called more then once"},{"line_number":99,"context_line":"        in a single python interpreter instance and raises the same exception"},{"line_number":100,"context_line":"        forever if its unrecoverable."},{"line_number":101,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"6fa5f38e_ac775be4","line":98,"range":{"start_line":98,"start_character":69,"end_line":98,"end_character":73},"in_reply_to":"62bb88ea_66ae0b47","updated":"2025-03-24 23:38:39.000000000","message":"Done","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"}],"nova/tests/unit/test_utils.py":[{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"40e2e02dc4dbea3255e23206073511fa05b8f9cf","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"77aa9996_019a32b6","line":1453,"updated":"2025-03-21 16:09:56.000000000","message":"I suggest to demonstrate the latching effect more precisely:\n\n    def test_wrapped_raises_forever(self):\n        expected \u003d LatchErrorOnRaiseTests.unrecoverable\n        first \u003d self.assertRaises(\n            type(expected), self.dummy_test_func, error\u003dexpected)\n        self.assertIs(expected, first)\n        expected \u003d LatchErrorOnRaiseTests.error\n        second \u003d self.assertRaises(\n            type(expected), self.dummy_test_func, error\u003dexpected)\n        self.assertIs(first, second)\n        expected \u003d None\n        third \u003d self.assertRaises(\n            type(expected), self.dummy_test_func, error\u003dexpected)\n        self.assertIs(first, third)","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"15ce1dac1fe609702fd4f80f9b30e8b0f186c8d7","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"dc5149be_04ecb0da","line":1453,"in_reply_to":"067f43c6_86acc533","updated":"2025-03-21 19:56:10.000000000","message":"If done this way then I agree the variable name should be changed from `expected` to something else but I think I see Bogdan\u0027s point. The current version isn\u0027t showing the dummy_test_func raising _different_ exceptions to show that aspect of the latch.\n\nI however noticed the test in nova/tests/unit/api/openstack/test_wsgi_app.py is demonstrating the behavior of raising the same original exception despite later calls raising different exceptions internally, so I think we have that part covered there.","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"8406997498ab6347cdec511357cb357930cf6a0b","unresolved":false,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"cc4b1c20_6f06b56f","line":1453,"in_reply_to":"0c6287b3_cf00ea4e","updated":"2025-03-24 10:54:42.000000000","message":"ack, that makes sense","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"08735dd2c3e1d36191f5e3e9b48ad337d8bccb0b","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf5fdc0e_7404057d","line":1453,"in_reply_to":"18becafa_ccfb4a43","updated":"2025-03-21 16:14:02.000000000","message":"Probably something like:\n\n    def test_wrapped_raises_forever(self):\n        expected \u003d LatchErrorOnRaiseTests.unrecoverable\n        first \u003d self.assertRaises(\n            type(expected), self.dummy_test_func, error\u003dexpected)\n        self.assertIs(expected, first)\n        expected \u003d LatchErrorOnRaiseTests.error\n        second \u003d self.assertRaises(\n            type(LatchErrorOnRaiseTests.unrecoverable),\n            self.dummy_test_func, error\u003dexpected)\n        self.assertIs(first, second)\n        expected \u003d None\n        third \u003d self.assertRaises(\n            type(LatchErrorOnRaiseTests.unrecoverable),\n            self.dummy_test_func, error\u003dexpected)\n        self.assertIs(first, third)\n        \nIt passes tox locally for me...","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"575034ff06efe9b6233e59f8258bde325fc90cd7","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"e080646a_08740f97","line":1453,"in_reply_to":"5797274c_545e1508","updated":"2025-03-21 20:13:30.000000000","message":"i.e. this: https://termbin.com/cpvj","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8c40a3a514854a2ab85c9b759d188c15e1b78e5c","unresolved":false,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"0c6287b3_cf00ea4e","line":1453,"in_reply_to":"6f4ee8fc_f8df7043","updated":"2025-03-21 20:54:41.000000000","message":"Acknowledged","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"e41712f39214230631945de591e52a27dbec07e5","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"18becafa_ccfb4a43","line":1453,"in_reply_to":"77aa9996_019a32b6","updated":"2025-03-21 16:10:54.000000000","message":"sorry, actually we should fix that example to compare the result with the same exception raised always","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2b7e7a3e748980cb97f664031e6ea8caa41fcc9","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"067f43c6_86acc533","line":1453,"in_reply_to":"bf5fdc0e_7404057d","updated":"2025-03-21 16:21:17.000000000","message":"What you have here does not make sense to me. You keep re-assigning `expected` to be what is _not_ expected.","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6cf9f4b375a6832e1fe557af8bcfff1c68bc41a4","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"5797274c_545e1508","line":1453,"in_reply_to":"dc5149be_04ecb0da","updated":"2025-03-21 20:06:05.000000000","message":"I see, so just raising something else in the line below would suffice right? I agree we\u0027re actually covered with the other one though, which I guess is why I didn\u0027t understand the point of the suggested change.","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6b02bab46009a5e62038ab7287615567e304a072","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"e2aa0aff_a0e7dbbc","line":1453,"in_reply_to":"e080646a_08740f97","updated":"2025-03-21 20:51:44.000000000","message":"right im intentionally not tryhing to show that here\n\nhttps://review.opendev.org/c/openstack/nova/+/945028/6/nova/tests/unit/api/openstack/test_wsgi_app.py#104\nshow that it never calls the funciton again.\n\nif you comment out the decorator and the call to reset in test.py\nthen that will fail because the excption changes.\n\nit does not chanvge because it never actully call the wrapped funciton again.\ni could assert that but that not the point of this test.\n\nthe latcih behaivo is demonstated by test_wrapped_raises_unrecoverable\nsimply by \n```\n self.assertIsNotNone(self.dummy_test_func.error)\n self.assertIs(self.dummy_test_func.error, expected)\n```\n\nthe latch is set if error is not none and i also asserted it set to the value i expect.\n \nim using self.assertIs(first, second) by the way to assert that its the same object in memory mot just equal but actully the exact same object.","commit_id":"6f673f90bd421e4492428936997f881849d52f46"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"88b2aca40f46f832e2e765a6edac8f51e0b3bed4","unresolved":true,"context_lines":[{"line_number":1450,"context_line":"        first \u003d self.assertRaises("},{"line_number":1451,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1452,"context_line":"        self.assertIs(expected, first)"},{"line_number":1453,"context_line":"        second \u003d self.assertRaises("},{"line_number":1454,"context_line":"            type(expected), self.dummy_test_func, error\u003dexpected)"},{"line_number":1455,"context_line":"        self.assertIs(first, second)"}],"source_content_type":"text/x-python","patch_set":6,"id":"6f4ee8fc_f8df7043","line":1453,"in_reply_to":"e2aa0aff_a0e7dbbc","updated":"2025-03-21 20:53:31.000000000","message":"i didnt fix this they way that was suggested as it not what i wanted this test to show but i added https://review.opendev.org/c/openstack/nova/+/945028/7/nova/tests/unit/api/openstack/test_wsgi_app.py#112","commit_id":"6f673f90bd421e4492428936997f881849d52f46"}],"nova/utils.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"4f25410408d0c9564c6b7dcbc288d58cb65a2246","unresolved":true,"context_lines":[{"line_number":1207,"context_line":"                return func(*args, **kwargs)"},{"line_number":1208,"context_line":"            else:"},{"line_number":1209,"context_line":"                raise wrapper.error"},{"line_number":1210,"context_line":"        except Exception as e:"},{"line_number":1211,"context_line":"            LOG.exception(e)"},{"line_number":1212,"context_line":"            wrapper.error \u003d e"},{"line_number":1213,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":1,"id":"b0e31c91_6ce3c59c","line":1210,"range":{"start_line":1210,"start_character":6,"end_line":1210,"end_character":30},"updated":"2025-03-19 17:05:49.000000000","message":"so either i add\n\n```\nexcept (know good excptions):\n  pass\n```\nbefore this or we invert and i only catch config errors here instead of Exception","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a595a652a18a8e09abbb3894e7e7bcfde8bca9ce","unresolved":false,"context_lines":[{"line_number":1207,"context_line":"                return func(*args, **kwargs)"},{"line_number":1208,"context_line":"            else:"},{"line_number":1209,"context_line":"                raise wrapper.error"},{"line_number":1210,"context_line":"        except Exception as e:"},{"line_number":1211,"context_line":"            LOG.exception(e)"},{"line_number":1212,"context_line":"            wrapper.error \u003d e"},{"line_number":1213,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":1,"id":"bf644709_2a104c2d","line":1210,"range":{"start_line":1210,"start_character":6,"end_line":1210,"end_character":30},"in_reply_to":"1303ed76_88ad234e","updated":"2025-03-20 14:04:16.000000000","message":"Done","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"65eb4ad4c29e43e4ccb41dde40d0e6ae27ab9ea9","unresolved":true,"context_lines":[{"line_number":1207,"context_line":"                return func(*args, **kwargs)"},{"line_number":1208,"context_line":"            else:"},{"line_number":1209,"context_line":"                raise wrapper.error"},{"line_number":1210,"context_line":"        except Exception as e:"},{"line_number":1211,"context_line":"            LOG.exception(e)"},{"line_number":1212,"context_line":"            wrapper.error \u003d e"},{"line_number":1213,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":1,"id":"1303ed76_88ad234e","line":1210,"range":{"start_line":1210,"start_character":6,"end_line":1210,"end_character":30},"in_reply_to":"b0e31c91_6ce3c59c","updated":"2025-03-20 13:51:54.000000000","message":"I suggest to catch only config errors for the beginning, to address the main issue.","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":6926,"name":"Bogdan Dobrelya","email":"bdobreli@redhat.com","username":"bogdando"},"change_message_id":"3565e715ed8210a8a9e87a6a03cbf58510a59907","unresolved":false,"context_lines":[{"line_number":1207,"context_line":"                return func(*args, **kwargs)"},{"line_number":1208,"context_line":"            else:"},{"line_number":1209,"context_line":"                raise wrapper.error"},{"line_number":1210,"context_line":"        except Exception as e:"},{"line_number":1211,"context_line":"            LOG.exception(e)"},{"line_number":1212,"context_line":"            wrapper.error \u003d e"},{"line_number":1213,"context_line":"            raise"}],"source_content_type":"text/x-python","patch_set":1,"id":"e9d92cf9_e70ef463","line":1210,"range":{"start_line":1210,"start_character":6,"end_line":1210,"end_character":30},"in_reply_to":"bf644709_2a104c2d","updated":"2025-03-20 14:27:26.000000000","message":"so could you please invert and only catch config errors here instead of Exception?","commit_id":"143f3bcc5dcbdac38d1ba20f1857c064139bc273"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f82455ab79143e7ab84e9a1f2b6c74627b83753e","unresolved":true,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"bb110a49_16eaf2a8","line":1219,"updated":"2025-03-20 14:23:16.000000000","message":"Not sure if I wasn\u0027t clear about my preference or if you decided to go this way specifically, but let me reiterate:\n\nI think we should default to latching behavior and exclude specific things we think _are_ recoverable. By definition, unknown unknowns can\u0027t be evaluated ahead of time and thus we can\u0027t make an informed decision about retrying. Since latching is the safer behavior I think it\u0027s better to poke through things like DB errors than to let something really fundamental like `ValueError` get retried. If I make a local edit, and include a typo, this code will continue retrying the code with a syntax error, which I don\u0027t think we want.\n\nWhat\u0027s the thinking behind only latching config exceptions specifically? Isn\u0027t it also possible/common that something would be invalid config, not raise an actual oslo error, but cause us to fail in some nova code in a very un-retry-able way?","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"f2db08f11644ed8eeeb54034843c0ee0b5afb4a8","unresolved":true,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"86298143_f50f7afe","line":1219,"in_reply_to":"6ba9ba41_d0fa2539","updated":"2025-03-20 15:18:32.000000000","message":"Literally the only thing I know of that should be retryable is the DB attempt to create or update the service ref. What else is retryable?\n\nWhat about all the things we don\u0027t know about? Retryable or not? If we don\u0027t know (and we can\u0027t) then we have to assume non-retryable I think. So that\u0027s one retryable thing and infinity non-retryable things :)\n\nAll the paste stuff comes at the end of `init_application()` which loads all the middleware things, parses that config file, etc. Seems like plenty of room for unretryable things there.","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"6a329206f286aa0cf181e48a009f4a36f5845217","unresolved":true,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"d847efaa_198ff557","line":1219,"in_reply_to":"86298143_f50f7afe","updated":"2025-03-20 15:27:21.000000000","message":"If I typo a thing in paste.ini that is supposed to be a class, I get:\n```\nMar 20 15:22:10 jammy devstack@n-api.service[55364]: ERROR nova AttributeError: module \u0027nova.api.openstack.urlmap\u0027 has no attribute \u0027urlmap_factoryy\u0027\n```\nSo gotta add `AttributeError` to the list of unretryables 😊\n\nI also expect there are things in the paste middleware that get initialized during the paste load, which could fail for any reason at all. So, add another infinity of things that could be unretryable... :P","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"7fc27d9ada140e064566e94b9b9745b9f6ce5fb1","unresolved":true,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"6ba9ba41_d0fa2539","line":1219,"in_reply_to":"bb110a49_16eaf2a8","updated":"2025-03-20 15:07:41.000000000","message":"simple i did not think there was a reasonable subset of error that we woudl ignore\nif you can produce that list i can invert the behavior.\n\ni actually asked Stephen offline if he would go with explicit catch of known fatal issues or catch all and  ignore know trainsitants and hew preferered the current approch. \n\ni was aware that you prefered the other approch and was expecting you to commnet on this.\n\nIf you can provide me with the list of exceptions to use, I can refactor.\n\nthis was simpler for me to reason about but im not too attached to this.\n\nexcept (safe,excpetion,list) : \npass\nexcept Excpetion:\nlatch \n\nis ok tooo","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":false,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"c5b52f4e_ab5ca923","line":1219,"in_reply_to":"d0ec0f3a_0da0f510","updated":"2025-03-20 18:21:39.000000000","message":"Acknowledged","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c6eccbf93110a1b61a0101f74286404567b806ea","unresolved":true,"context_lines":[{"line_number":1216,"context_line":"        # there can be other but for now we are being conservitve."},{"line_number":1217,"context_line":"        # if this decorator is reused for other edgcases in the future we"},{"line_number":1218,"context_line":"        # may need to take the error_set as an import to the decorator."},{"line_number":1219,"context_line":"        # for now we keep this simple."},{"line_number":1220,"context_line":"        except cfg.Error as e:"},{"line_number":1221,"context_line":"            LOG.exception(e)"},{"line_number":1222,"context_line":"            wrapper.error \u003d e"}],"source_content_type":"text/x-python","patch_set":3,"id":"d0ec0f3a_0da0f510","line":1219,"in_reply_to":"d847efaa_198ff557","updated":"2025-03-20 15:29:48.000000000","message":"Here\u0027s a simulated failure in a paste application\u0027s app factory, which is called from our paste load:\n```\nMar 20 15:28:54 jammy devstack@n-api.service[56498]: ERROR nova   File \"/opt/stack/data/venv/lib/python3.10/site-packages/keystonemiddleware/auth_token/__init__.py\", line 895, in filter_factory\nMar 20 15:28:54 jammy devstack@n-api.service[56498]: ERROR nova     raise RuntimeError()\n```","commit_id":"35dba0e6bd73421cb16f4b65180343338454b91e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":true,"context_lines":[{"line_number":1197,"context_line":"    return outer_wrapper"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":""},{"line_number":1200,"context_line":"def latch_error_on_raise(retryable\u003d(odbe.DBConnectionError,)):"},{"line_number":1201,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1202,"context_line":"    it will always raise the same exception going forward."},{"line_number":1203,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"b82e7530_5832ba8a","line":1200,"range":{"start_line":1200,"start_character":4,"end_line":1200,"end_character":62},"updated":"2025-03-20 18:21:39.000000000","message":"so there are two possible changes i am considering makeign to this version then im more or less happy with this desgin,\n\npart of me is happy with this refactor becasue this is now a resuabel decorator\nbut the one thing im considering changing in the signigure is this\n\n```\nsentinel \nclass UnusedSentinelException(exception):\npass\n\ndef latch_error_on_raise(retryable\u003d(UnusedSentinelException,)):\n```\n\nif i make that change nothing will ever raise `UnusedSentinelException`\nso by default this will latch all excptions and i can just pass\n\nretryable\u003d(odbe.DBConnectionError,)\n\nwhen i apply this to the `wsgi_app.init_application` function.\n\ni think that is a better api but i only tought of that now.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77201f84d3f22c65ac7a7acb3a4d8771f6888c61","unresolved":true,"context_lines":[{"line_number":1197,"context_line":"    return outer_wrapper"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":""},{"line_number":1200,"context_line":"def latch_error_on_raise(retryable\u003d(odbe.DBConnectionError,)):"},{"line_number":1201,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1202,"context_line":"    it will always raise the same exception going forward."},{"line_number":1203,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ffa329c8_b446e1f8","line":1200,"range":{"start_line":1200,"start_character":4,"end_line":1200,"end_character":62},"in_reply_to":"b82e7530_5832ba8a","updated":"2025-03-20 18:29:01.000000000","message":"Yeah I agree that it makes sense for the default behavior to be \"latch anything\" and then pass in the list of things you want to not latch, per use.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":1197,"context_line":"    return outer_wrapper"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":""},{"line_number":1200,"context_line":"def latch_error_on_raise(retryable\u003d(odbe.DBConnectionError,)):"},{"line_number":1201,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1202,"context_line":"    it will always raise the same exception going forward."},{"line_number":1203,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"68e5ba2f_a630c9e7","line":1200,"range":{"start_line":1200,"start_character":4,"end_line":1200,"end_character":62},"in_reply_to":"ffa329c8_b446e1f8","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":1197,"context_line":"    return outer_wrapper"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":""},{"line_number":1200,"context_line":"def latch_error_on_raise(retryable\u003d(odbe.DBConnectionError,)):"},{"line_number":1201,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1202,"context_line":"    it will always raise the same exception going forward."},{"line_number":1203,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7f8cc99d_8ff73f97","line":1200,"range":{"start_line":1200,"start_character":4,"end_line":1200,"end_character":62},"in_reply_to":"ffa329c8_b446e1f8","updated":"2025-03-21 15:43:15.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77201f84d3f22c65ac7a7acb3a4d8771f6888c61","unresolved":true,"context_lines":[{"line_number":1213,"context_line":"                if not wrapper.error:"},{"line_number":1214,"context_line":"                    return func(*args, **kwargs)"},{"line_number":1215,"context_line":"                else:"},{"line_number":1216,"context_line":"                    raise wrapper.error"},{"line_number":1217,"context_line":"            except retryable:"},{"line_number":1218,"context_line":"                # reraise any retryable exception to allow them to be handled"},{"line_number":1219,"context_line":"                # by the caller."}],"source_content_type":"text/x-python","patch_set":4,"id":"350effa6_8357a26d","line":1216,"updated":"2025-03-20 18:29:01.000000000","message":"So, this will always be going back through your exception handler, effectively always doing `wrapper.error \u003d wrapper.error`. Are you doing this to keep your `LOG.exception` going each time? To me, this seems recursive and so if it were me I would make this:\n```\nif wrapper.error:\n    raise wrapper.error\ntry:\n    return func(*args, **kwargs)\nexcept Exception as e:\n    wrapper.error \u003d e\n    LOG.exception(e)\n    raise\n```\n\nAlso note I put the `LOG` call after the recording of the current error. Log statements can fail too and I think we want to make sure we latch before we have an opportunity to fail and prevent that from happening right?","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"dd8e1c5cf53b5306bd722e1388d6f75eaa4f0c78","unresolved":true,"context_lines":[{"line_number":1213,"context_line":"                if not wrapper.error:"},{"line_number":1214,"context_line":"                    return func(*args, **kwargs)"},{"line_number":1215,"context_line":"                else:"},{"line_number":1216,"context_line":"                    raise wrapper.error"},{"line_number":1217,"context_line":"            except retryable:"},{"line_number":1218,"context_line":"                # reraise any retryable exception to allow them to be handled"},{"line_number":1219,"context_line":"                # by the caller."}],"source_content_type":"text/x-python","patch_set":4,"id":"bb589567_b5a08ea9","line":1216,"in_reply_to":"350effa6_8357a26d","updated":"2025-03-20 19:35:33.000000000","message":"i am doing `wrapper.error \u003d e`\nbecause i used to work at intel and even if this is python they have drumb into me that an assicment is alwasy faster then a comparison.\n\nthere is no opportunity for a branch prediction miss.\n\nack on the reorder of the log an assignment and yes\n\ni can early retrun that is also branch predictor frequently because it should predict the if is not taken and if it ever is it always will be form that point on.\n\nso ill make those changes in the next version","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"c45388580c286b98695e41866e3f2c5c4c6540e5","unresolved":true,"context_lines":[{"line_number":1213,"context_line":"                if not wrapper.error:"},{"line_number":1214,"context_line":"                    return func(*args, **kwargs)"},{"line_number":1215,"context_line":"                else:"},{"line_number":1216,"context_line":"                    raise wrapper.error"},{"line_number":1217,"context_line":"            except retryable:"},{"line_number":1218,"context_line":"                # reraise any retryable exception to allow them to be handled"},{"line_number":1219,"context_line":"                # by the caller."}],"source_content_type":"text/x-python","patch_set":4,"id":"ce07f311_3e6f1ed3","line":1216,"in_reply_to":"bb589567_b5a08ea9","updated":"2025-03-20 20:14:33.000000000","message":"Yeah, it works it just keeps changing a thing, which seems less good to me. Like if you put a debugger on that memory location (if this wasn\u0027t python) it would be a thing trying to be static that is constantly changing a pointer value, even though the pointer value keeps going to the same type of thing, which is a copy of the original thing :)","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":1213,"context_line":"                if not wrapper.error:"},{"line_number":1214,"context_line":"                    return func(*args, **kwargs)"},{"line_number":1215,"context_line":"                else:"},{"line_number":1216,"context_line":"                    raise wrapper.error"},{"line_number":1217,"context_line":"            except retryable:"},{"line_number":1218,"context_line":"                # reraise any retryable exception to allow them to be handled"},{"line_number":1219,"context_line":"                # by the caller."}],"source_content_type":"text/x-python","patch_set":4,"id":"55789895_ced767bb","line":1216,"in_reply_to":"ce07f311_3e6f1ed3","updated":"2025-03-21 15:43:15.000000000","message":"Acknowledged","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":1213,"context_line":"                if not wrapper.error:"},{"line_number":1214,"context_line":"                    return func(*args, **kwargs)"},{"line_number":1215,"context_line":"                else:"},{"line_number":1216,"context_line":"                    raise wrapper.error"},{"line_number":1217,"context_line":"            except retryable:"},{"line_number":1218,"context_line":"                # reraise any retryable exception to allow them to be handled"},{"line_number":1219,"context_line":"                # by the caller."}],"source_content_type":"text/x-python","patch_set":4,"id":"7a151419_0bfbe20e","line":1216,"in_reply_to":"ce07f311_3e6f1ed3","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"c67efa95a3285fc809a5d5855594c45c984ba8d2","unresolved":true,"context_lines":[{"line_number":1219,"context_line":"                # by the caller."},{"line_number":1220,"context_line":"                raise"},{"line_number":1221,"context_line":"            except Exception as e:"},{"line_number":1222,"context_line":"                LOG.exception(e)"},{"line_number":1223,"context_line":"                wrapper.error \u003d e"},{"line_number":1224,"context_line":"                raise"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"        wrapper.error \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fbc2f5a_b38cc2bc","line":1223,"range":{"start_line":1222,"start_character":0,"end_line":1223,"end_character":33},"updated":"2025-03-20 18:21:39.000000000","message":"the other change i am conidering is wrapping this in an if that will check an environment variable allow this to be disabled if really needed for some reason.\n\nlike we do for monkey patching\n\nhttps://github.com/openstack/nova/blob/76c3c4c1bd03298794e1e3fb471c4506c9a38ee0/nova/monkey_patch.py#L72-L78\n\nsomething like this\n```\nif (os.environ.get(\u0027OS_NOVA_DISABLE_LATCH_ON_ERROR\u0027, \u0027\u0027).lower()\n        not in (\u00271\u0027, \u0027true\u0027, \u0027yes\u0027)):\n     LOG.exception(e)\n     wrapper.error \u003d e\nraise\n```\n\nit the `wrapper.error \u003d e` assignment that triggers the new behavior so if i just dont do that then we treat it like a retryable error.\n\nincluding the logging in the if is just to make the side effect entirely disappear.\n\nlet me know if you think this is needed or is that over engineering it for now reason.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":1219,"context_line":"                # by the caller."},{"line_number":1220,"context_line":"                raise"},{"line_number":1221,"context_line":"            except Exception as e:"},{"line_number":1222,"context_line":"                LOG.exception(e)"},{"line_number":1223,"context_line":"                wrapper.error \u003d e"},{"line_number":1224,"context_line":"                raise"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"        wrapper.error \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"0b7342a0_67915c69","line":1223,"range":{"start_line":1222,"start_character":0,"end_line":1223,"end_character":33},"in_reply_to":"0d11862b_efcb478b","updated":"2025-03-21 15:38:45.000000000","message":"Acknowledged","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":1219,"context_line":"                # by the caller."},{"line_number":1220,"context_line":"                raise"},{"line_number":1221,"context_line":"            except Exception as e:"},{"line_number":1222,"context_line":"                LOG.exception(e)"},{"line_number":1223,"context_line":"                wrapper.error \u003d e"},{"line_number":1224,"context_line":"                raise"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"        wrapper.error \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"6d3bc228_c9ed94b8","line":1223,"range":{"start_line":1222,"start_character":0,"end_line":1223,"end_character":33},"in_reply_to":"0d11862b_efcb478b","updated":"2025-03-21 15:43:15.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"dd8e1c5cf53b5306bd722e1388d6f75eaa4f0c78","unresolved":true,"context_lines":[{"line_number":1219,"context_line":"                # by the caller."},{"line_number":1220,"context_line":"                raise"},{"line_number":1221,"context_line":"            except Exception as e:"},{"line_number":1222,"context_line":"                LOG.exception(e)"},{"line_number":1223,"context_line":"                wrapper.error \u003d e"},{"line_number":1224,"context_line":"                raise"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"        wrapper.error \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"0d11862b_efcb478b","line":1223,"range":{"start_line":1222,"start_character":0,"end_line":1223,"end_character":33},"in_reply_to":"4e0d4f92_014bd4fc","updated":"2025-03-20 19:35:33.000000000","message":"ok im just not going to add this then.\ni dont really want to make the envionment vaiable an api contract which i would be if i was to add it and if we use this again for something esle a global toggle does not sound like a good thing.\n\n\nunless melaine or others object ill just resolve this this comment thread when i push the next version without adding this escape hatch.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"77201f84d3f22c65ac7a7acb3a4d8771f6888c61","unresolved":true,"context_lines":[{"line_number":1219,"context_line":"                # by the caller."},{"line_number":1220,"context_line":"                raise"},{"line_number":1221,"context_line":"            except Exception as e:"},{"line_number":1222,"context_line":"                LOG.exception(e)"},{"line_number":1223,"context_line":"                wrapper.error \u003d e"},{"line_number":1224,"context_line":"                raise"},{"line_number":1225,"context_line":""},{"line_number":1226,"context_line":"        wrapper.error \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"4e0d4f92_014bd4fc","line":1223,"range":{"start_line":1222,"start_character":0,"end_line":1223,"end_character":33},"in_reply_to":"5fbc2f5a_b38cc2bc","updated":"2025-03-20 18:29:01.000000000","message":"I don\u0027t really care much either way. It\u0027s fine to have a flag to let people opt out if this has some unintended behavioral change they can\u0027t deal with in short order. But, I think this is fine to just always do, until someone complains.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":true,"context_lines":[{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to ack as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"}],"source_content_type":"text/x-python","patch_set":5,"id":"60bd81e0_cf521002","line":1200,"range":{"start_line":1200,"start_character":27,"end_line":1200,"end_character":30},"updated":"2025-03-21 15:38:45.000000000","message":"\"act\"","commit_id":"6e0cdd386cfa3e77983e366002630def4ecbcd2d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d7a0810ffdddcfed61e7edd24e4cc385c76d5d8a","unresolved":false,"context_lines":[{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to ack as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"}],"source_content_type":"text/x-python","patch_set":5,"id":"9da294c5_ba5555b0","line":1200,"range":{"start_line":1200,"start_character":27,"end_line":1200,"end_character":30},"in_reply_to":"60bd81e0_cf521002","updated":"2025-03-21 15:46:29.000000000","message":"Done","commit_id":"6e0cdd386cfa3e77983e366002630def4ecbcd2d"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":true,"context_lines":[{"line_number":1196,"context_line":"    return outer_wrapper"},{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3a21a584_f14265cb","line":1199,"range":{"start_line":1199,"start_character":6,"end_line":1199,"end_character":24},"updated":"2025-03-24 23:17:24.000000000","message":"SentinelException","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"9a302358021b505b505cee30aa76080d2fe530e9","unresolved":false,"context_lines":[{"line_number":1196,"context_line":"    return outer_wrapper"},{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"5a4557f3_89870f51","line":1199,"range":{"start_line":1199,"start_character":6,"end_line":1199,"end_character":24},"in_reply_to":"3a21a584_f14265cb","updated":"2025-04-15 02:59:39.000000000","message":"Done","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":true,"context_lines":[{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"}],"source_content_type":"text/x-python","patch_set":7,"id":"e686fea9_83f53a37","line":1200,"range":{"start_line":1200,"start_character":27,"end_line":1200,"end_character":31},"updated":"2025-03-24 23:17:24.000000000","message":"act","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e1e0308487428d257f4a201542d7588f5d7dd143","unresolved":false,"context_lines":[{"line_number":1197,"context_line":""},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"class _SentinelExcpetion(Exception):"},{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"}],"source_content_type":"text/x-python","patch_set":7,"id":"178e451a_3385617f","line":1200,"range":{"start_line":1200,"start_character":27,"end_line":1200,"end_character":31},"in_reply_to":"e686fea9_83f53a37","updated":"2025-03-24 23:38:39.000000000","message":"oh i fixed this incorrectly with a differtne typo\n\n`ack` -\u003e `acks` instead of `act` ...","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":true,"context_lines":[{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"},{"line_number":1204,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1205,"context_line":"    it will always raise the same exception going forward."},{"line_number":1206,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"65b4fd4f_1efedd15","line":1203,"range":{"start_line":1203,"start_character":36,"end_line":1203,"end_character":54},"updated":"2025-03-24 23:17:24.000000000","message":"Same","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"9a302358021b505b505cee30aa76080d2fe530e9","unresolved":false,"context_lines":[{"line_number":1200,"context_line":"    \"\"\"This type exists to acks as a placeholder and will never be raised\"\"\""},{"line_number":1201,"context_line":""},{"line_number":1202,"context_line":""},{"line_number":1203,"context_line":"def latch_error_on_raise(retryable\u003d(_SentinelExcpetion,)):"},{"line_number":1204,"context_line":"    \"\"\"This is a utility decorator to ensure if a function ever raises"},{"line_number":1205,"context_line":"    it will always raise the same exception going forward."},{"line_number":1206,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"59b8c132_780ce821","line":1203,"range":{"start_line":1203,"start_character":36,"end_line":1203,"end_character":54},"in_reply_to":"65b4fd4f_1efedd15","updated":"2025-04-15 02:59:39.000000000","message":"Done","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e6eb05c8abacfaea9e96740c171ae5d70efe2109","unresolved":true,"context_lines":[{"line_number":1205,"context_line":"    it will always raise the same exception going forward."},{"line_number":1206,"context_line":""},{"line_number":1207,"context_line":"    The only exception we know is safe to ignore is an oslo db connection"},{"line_number":1208,"context_line":"    error as the db may be temporally unavailable and we should allow"},{"line_number":1209,"context_line":"    mod_wsgi to retry"},{"line_number":1210,"context_line":"    \"\"\""},{"line_number":1211,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"49882ab3_dcbbd5d3","line":1208,"range":{"start_line":1208,"start_character":27,"end_line":1208,"end_character":37},"updated":"2025-03-24 23:17:24.000000000","message":"temporarily","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e1e0308487428d257f4a201542d7588f5d7dd143","unresolved":false,"context_lines":[{"line_number":1205,"context_line":"    it will always raise the same exception going forward."},{"line_number":1206,"context_line":""},{"line_number":1207,"context_line":"    The only exception we know is safe to ignore is an oslo db connection"},{"line_number":1208,"context_line":"    error as the db may be temporally unavailable and we should allow"},{"line_number":1209,"context_line":"    mod_wsgi to retry"},{"line_number":1210,"context_line":"    \"\"\""},{"line_number":1211,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"fb797b32_08661049","line":1208,"range":{"start_line":1208,"start_character":27,"end_line":1208,"end_character":37},"in_reply_to":"49882ab3_dcbbd5d3","updated":"2025-03-24 23:38:39.000000000","message":"... ok the problem with me spell-checking things is I sometimes select the wrong word.","commit_id":"0bde6c4c5502635690347e962ce8a8efd98005c5"}],"releasenotes/notes/latch-error-on-raise-cf2da71a12b5f55f.yaml":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":true,"context_lines":[{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    In previous releases we addressed https://bugs.launchpad.net/nova/+bug/1882094"},{"line_number":5,"context_line":"    (a bug with how mod_wsgi reloads wsgi application into the same python"},{"line_number":6,"context_line":"    interpreter on error) by wrapping the initialization of global data in"},{"line_number":7,"context_line":"    a run_once decorator. The run_once decorator solves the reentrancy problem"},{"line_number":8,"context_line":"    for the initialization of the config objects or other global state that"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"4b451a47_5b3c2fb5","line":5,"range":{"start_line":5,"start_character":42,"end_line":5,"end_character":53},"updated":"2025-03-21 13:59:52.000000000","message":"\"applications\"","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    In previous releases we addressed https://bugs.launchpad.net/nova/+bug/1882094"},{"line_number":5,"context_line":"    (a bug with how mod_wsgi reloads wsgi application into the same python"},{"line_number":6,"context_line":"    interpreter on error) by wrapping the initialization of global data in"},{"line_number":7,"context_line":"    a run_once decorator. The run_once decorator solves the reentrancy problem"},{"line_number":8,"context_line":"    for the initialization of the config objects or other global state that"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"cf6fd851_48bb837e","line":5,"range":{"start_line":5,"start_character":42,"end_line":5,"end_character":53},"in_reply_to":"4b451a47_5b3c2fb5","updated":"2025-03-21 15:43:15.000000000","message":"Acknowledged","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    In previous releases we addressed https://bugs.launchpad.net/nova/+bug/1882094"},{"line_number":5,"context_line":"    (a bug with how mod_wsgi reloads wsgi application into the same python"},{"line_number":6,"context_line":"    interpreter on error) by wrapping the initialization of global data in"},{"line_number":7,"context_line":"    a run_once decorator. The run_once decorator solves the reentrancy problem"},{"line_number":8,"context_line":"    for the initialization of the config objects or other global state that"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"87b58ef2_e3bcb2b3","line":5,"range":{"start_line":5,"start_character":42,"end_line":5,"end_character":53},"in_reply_to":"4b451a47_5b3c2fb5","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":true,"context_lines":[{"line_number":10,"context_line":"    This allows the nova wsgi application to be reloaded and retried when"},{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"65fc4ef5_5b36231a","line":13,"range":{"start_line":13,"start_character":49,"end_line":13,"end_character":59},"updated":"2025-03-21 13:59:52.000000000","message":"\"side effect\"","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":10,"context_line":"    This allows the nova wsgi application to be reloaded and retried when"},{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"cfb4506c_fc77b8de","line":13,"range":{"start_line":13,"start_character":49,"end_line":13,"end_character":59},"in_reply_to":"65fc4ef5_5b36231a","updated":"2025-03-21 15:43:15.000000000","message":"Acknowledged","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":10,"context_line":"    This allows the nova wsgi application to be reloaded and retried when"},{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"96ba3535_ee6db1b0","line":13,"range":{"start_line":13,"start_character":49,"end_line":13,"end_character":59},"in_reply_to":"65fc4ef5_5b36231a","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":true,"context_lines":[{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"},{"line_number":17,"context_line":"    obviously a bug. When run under other wsgi servers config errors cause"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"b2aba904_ea49821b","line":14,"range":{"start_line":14,"start_character":27,"end_line":14,"end_character":40},"updated":"2025-03-21 13:59:52.000000000","message":"non-transient","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"},{"line_number":17,"context_line":"    obviously a bug. When run under other wsgi servers config errors cause"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"bb041c51_f22c7c89","line":14,"range":{"start_line":14,"start_character":27,"end_line":14,"end_character":40},"in_reply_to":"b2aba904_ea49821b","updated":"2025-03-21 15:43:15.000000000","message":"Acknowledged","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":11,"context_line":"    transient errors, such as the db being unavailable when the api starts,"},{"line_number":12,"context_line":"    to heal overtime."},{"line_number":13,"context_line":"    The run_once decorator also had an unplanned sideeffect. If the nova-api"},{"line_number":14,"context_line":"    raised an error for an non transient issue such as invalid config that would"},{"line_number":15,"context_line":"    be raised only once and nova would serve subsequent requests with a partly"},{"line_number":16,"context_line":"    initialized config. This will lead to undefined behavior and is"},{"line_number":17,"context_line":"    obviously a bug. When run under other wsgi servers config errors cause"}],"source_content_type":"text/x-yaml","patch_set":4,"id":"692b7ccf_0a564020","line":14,"range":{"start_line":14,"start_character":27,"end_line":14,"end_character":40},"in_reply_to":"b2aba904_ea49821b","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"9bc6a8ad71101d8ba4d4a75e793983889341790c","unresolved":true,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    Note that the generic oslo healthcheck middleware cannot help report application"},{"line_number":35,"context_line":"    specific fatal error like config error as it only notifies you that the wsgi"},{"line_number":36,"context_line":"    server i.e. mod_wsgi is alive."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"dac983d0_d0b67fc7","line":36,"updated":"2025-03-21 13:59:52.000000000","message":"TBH, this feels like too much detail for a reno to me. It\u0027s all good stuff, but for the average operator I feel like this is a lot to read and includes too much detail.\n\nCould we not just do something like:\n\n\u003e Nova-api will now detect fatal errors (configuration, et al) on startup and lock into a permanent error state until fixed and restarted. This solves a problem with some wsgi containers ignoring initialization errors and continuing to send requests to the half-initialized service. See bug $blah for more details.","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e228e278cc36721edceab0abe06c14921f020625","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    Note that the generic oslo healthcheck middleware cannot help report application"},{"line_number":35,"context_line":"    specific fatal error like config error as it only notifies you that the wsgi"},{"line_number":36,"context_line":"    server i.e. mod_wsgi is alive."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"71afe74a_bf2c187b","line":36,"in_reply_to":"d9dcc140_ef6aae54","updated":"2025-03-21 15:38:45.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a14eae4ac0d2a6bf8a19623d28c0590db85d7daf","unresolved":false,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    Note that the generic oslo healthcheck middleware cannot help report application"},{"line_number":35,"context_line":"    specific fatal error like config error as it only notifies you that the wsgi"},{"line_number":36,"context_line":"    server i.e. mod_wsgi is alive."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"7e5fe0f6_1c9d0bf8","line":36,"in_reply_to":"d9dcc140_ef6aae54","updated":"2025-03-21 15:43:15.000000000","message":"Done","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5eab3143a2e3078f08b9b68825ff33bca4172def","unresolved":true,"context_lines":[{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    Note that the generic oslo healthcheck middleware cannot help report application"},{"line_number":35,"context_line":"    specific fatal error like config error as it only notifies you that the wsgi"},{"line_number":36,"context_line":"    server i.e. mod_wsgi is alive."}],"source_content_type":"text/x-yaml","patch_set":4,"id":"d9dcc140_ef6aae54","line":36,"in_reply_to":"dac983d0_d0b67fc7","updated":"2025-03-21 14:33:18.000000000","message":"sure\ni was going to have a short release note but i had most of this text written for the Workaound config option i ened up not creating.\n\nfor the config option i though i would need to explian properly why you shoudl set it but obvioulsy a config option to contole how we handel broken config was never gong to work right.\n\ni agree its a bit much ill trim this down","commit_id":"f9d60100ad329ccb016999ae8653d21cf1a386be"}]}
