[{"data":1,"prerenderedAt":62},["ShallowReactive",2],{"qa-\u002Fpython\u002Fexceptions\u002Ftry-except":3},{"page":4,"siblings":52,"blog":43},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":12,"path":20,"questions":21,"related":43,"seo":44,"seoDescription":45,"stem":46,"subtopic":47,"topic":48,"topicSlug":49,"updated":50,"__hash__":51},"qa\u002Fpython\u002Fexceptions\u002Ftry-except.md","Try Except",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,"\u002Fpython\u002Fexceptions\u002Ftry-except",[22,26,30,34,39],{"id":23,"difficulty":14,"q":24,"a":25},"four-clauses","What do the try, except, else, and finally clauses do and when does each run?","A full statement has four parts. **`try`** holds the code that might fail.\n**`except`** runs only if a matching exception was raised in `try`. **`else`**\nruns only if `try` finished **without** raising — it's for the \"success path\"\ncode you don't want wrapped in the `try`. **`finally`** runs **always**, whether\nthere was an exception or not, and even if you `return`\u002F`break` — it's for cleanup.\n\n```python\ntry:\n    conn = open_db()          # might raise\nexcept DBError as e:\n    log(e)                    # runs only on failure\nelse:\n    conn.commit()             # runs only on success\nfinally:\n    conn.close()              # always runs — cleanup\n```\n\nPutting the success-only code in `else` (instead of at the bottom of `try`) keeps\nthe `try` block narrow, so `except` only catches errors from the risky line.\n",{"id":27,"difficulty":14,"q":28,"a":29},"catch-multiple","How do you catch multiple exception types, and what does `as e` give you?","Group related types in a **tuple** after `except`, or use separate `except`\nclauses when each needs different handling. The `as e` binds the **exception\ninstance**, letting you inspect its message, args, or attributes.\n\n```python\ntry:\n    value = int(raw)\nexcept (ValueError, TypeError) as e:   # tuple -> one handler for both\n    print(f\"bad input: {e}\")           # e is the exception object\nexcept KeyError:                       # separate handler, different logic\n    print(\"missing key\")\n```\n\nClauses are checked **top to bottom**, and the **first match wins** — so order\nspecific exceptions before their base classes. Use the tuple form when several\ntypes share handling; use separate clauses when they don't.\n",{"id":31,"difficulty":14,"q":32,"a":33},"bare-except","Why is a bare `except:` considered bad practice?","A bare `except:` (or `except BaseException:`) catches **everything** — including\n`KeyboardInterrupt` and `SystemExit`, which are how the user Ctrl-Cs or the\nprogram exits. It also **swallows bugs** like `NameError` or `TypeError` that you'd\nrather see crash loudly, making problems invisible.\n\n```python\ntry:\n    do_work()\nexcept:                 # too broad — even Ctrl-C is caught\n    pass                # silent failure — hides real bugs\n\ntry:\n    do_work()\nexcept Exception as e:  # catches errors, not Ctrl-C \u002F SystemExit\n    log.exception(e)    # at least record what happened\n```\n\nCatch the **narrowest** exception you can actually handle. If you must catch\nbroadly, use `except Exception` (not bare), and always log rather than silently\n`pass`.\n",{"id":35,"difficulty":36,"q":37,"a":38},"finally-return","hard","What happens when `finally` contains a `return`?","`finally` always runs, even when `try` or `except` already has a `return`. If\n`finally` itself **returns** (or raises), it **overrides** the pending return or\nexception — the value from `try`\u002F`except` is silently discarded. This is a classic\ngotcha.\n\n```python\ndef f():\n    try:\n        return 1        # value queued...\n    finally:\n        return 2        # ...but finally's return wins\nf()                     # 2, not 1\n\ndef g():\n    try:\n        raise ValueError\n    finally:\n        return \"swallowed\"   # finally return suppresses the exception!\ng()                     # \"swallowed\" — exception vanishes\n```\n\nAvoid `return`\u002F`break` inside `finally`: it masks both return values and\nexceptions. Keep `finally` for cleanup only.\n",{"id":40,"difficulty":36,"q":41,"a":42},"reraise-chaining","How do you re-raise an exception and what is exception chaining?","A bare **`raise`** (no argument) inside an `except` block **re-raises the current\nexception**, preserving its original traceback — useful for logging then letting it\npropagate. To translate one error into another while keeping the cause, use\n**`raise NewError from original`**, which sets `__cause__` and shows both in the\ntraceback.\n\n```python\ntry:\n    parse(config)\nexcept KeyError as e:\n    log.error(\"config invalid\")\n    raise                       # re-raise same exception, original traceback\n\ntry:\n    value = data[\"port\"]\nexcept KeyError as e:\n    raise ConfigError(\"missing port\") from e   # explicit chaining\n```\n\nWhen an exception is raised **inside** an `except` block without `from`, Python\nstill links it implicitly via `__context__` (\"During handling of the above...\"). Use\n`from e` to make the cause explicit, or `from None` to suppress the chain.\n",null,{"description":11},"Python interview questions on try\u002Fexcept\u002Felse\u002Ffinally, catching multiple exception types, why bare except is bad, finally with return, and exception chaining with raise from.","python\u002Fexceptions\u002Ftry-except","try \u002F except \u002F else \u002F finally","Errors & Exceptions","exceptions","2026-06-18","zypRLfxfYjZySj7ZLjRlUt8LzLvDa0sVDs3sO4N7lzk",[53,57,58],{"subtopic":54,"path":55,"order":56},"Context Managers & with","\u002Fpython\u002Fexceptions\u002Fcontext-managers",1,{"subtopic":47,"path":20,"order":12},{"subtopic":59,"path":60,"order":61},"Custom Exceptions & the Hierarchy","\u002Fpython\u002Fexceptions\u002Fcustom-exceptions",3,1781808680863]