Skip to content

feat: enhance error handling from terminal output for MAPDL launch #3969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jun 2, 2025

Conversation

germa89
Copy link
Collaborator

@germa89 germa89 commented May 29, 2025

Description

As the title. Now we also consider the stderr output before raising an error.

Implemented class QueueWithPermanentStorage which allows for checking the full output for both stdout and stderr.

Issue linked

Close #3963

Checklist

Summary by Sourcery

Enhance MAPDL launch error handling by capturing and persisting both stdout and stderr outputs and mapping common launch failures to user-friendly exceptions.

New Features:

  • Include stderr output in failure messages when MAPDL fails to start.
  • Introduce handle_launch_exception to translate MPI and licensing errors into specific, user-friendly exceptions.

Bug Fixes:

  • Fix typo in empty_attempts variable name in server aliveness check loop.

Enhancements:

  • Add QueueWithPermanentStorage to retain all terminal output for post-mortem inspection.
  • Refactor standard-output retrieval to return aggregated text instead of lists.

Documentation:

  • Extend troubleshooting guide with guidance for MPI configuration and license availability issues.

@germa89 germa89 requested a review from a team as a code owner May 29, 2025 09:37
@ansys-reviewer-bot
Copy link
Contributor

Thanks for opening a Pull Request. If you want to perform a review write a comment saying:

@ansys-reviewer-bot review

Copy link
Contributor

sourcery-ai bot commented May 29, 2025

Reviewer's Guide

This PR improves the MAPDL launch workflow by capturing and persisting full terminal output (stdout and stderr), refactoring how output is collected, and providing user-friendly error handling with new exception types.

Sequence Diagram: Retrieving Full Stdout/Stderr in check_mapdl_launch

sequenceDiagram
    participant C as "Caller (e.g. launch_mapdl)"
    participant CL as "check_mapdl_launch"
    participant SQ_OUT as "stdout_queue (QueueWithPermanentStorage)"
    participant SQ_ERR as "stderr_queue (QueueWithPermanentStorage)"

    C->>CL: Initiate MAPDL Launch and Check
    activate CL

    alt MAPDL Launch Fails
        CL->>SQ_ERR: _get_std_output(stderr_queue)
        activate SQ_ERR
        SQ_ERR-->>CL: stderr_text (from .storage_text)
        deactivate SQ_ERR

        CL->>SQ_OUT: _get_std_output(stdout_queue)
        activate SQ_OUT
        SQ_OUT-->>CL: stdout_text (from .storage_text)
        deactivate SQ_OUT

        CL->>CL: Construct detailed error message (using stdout_text, stderr_text)
        CL-->>C: raise MapdlDidNotStart(detailed_message)
    end
    deactivate CL
Loading

Class Diagram: Error Handling and Queue Enhancements

classDiagram
    class Queue {
        <<Python Standard Library 'queue.Queue'>>
        +get()
    }
    class QueueWithPermanentStorage {
        -_storage: list~Any~
        +storage: list~Any~
        +storage_text: str
        +__init__(*args, **kwargs)
        +get(*args, **kwargs) Any
    }
    Queue <|-- QueueWithPermanentStorage

    class MapdlDidNotStart {
        <<Exception>>
        +__init__(msg: str)
    }
    class NotAvailableLicenses {
        <<Exception>>
        +__init__(msg: str)
    }
    class IncorrectMPIConfigurationError {
        <<Exception>>
        +__init__(msg: str)
    }
    MapdlDidNotStart <|-- NotAvailableLicenses
    MapdlDidNotStart <|-- IncorrectMPIConfigurationError
Loading

Flow Diagram: handle_launch_exception Logic

graph TD
    A["Start: handle_launch_exception(exception)"] --> B["Extract exception_msg"];
    B --> C{"'mpirun: command not found' in msg?"};
    C -- Yes --> D["Return IncorrectMPIConfigurationError"];
    D --> Z["End"];
    C -- No --> E{"'ANSYS license not available' in msg?"};
    E -- Yes --> G["Return NotAvailableLicenses"];
    G --> Z;
    E -- No --> H["Return original exception"];
    H --> Z;
Loading

File-Level Changes

Change Details Files
Enhance error message composition with stderr
  • Initialize stderr queue alongside stdout
  • Append stderr output to error message when present
  • Include stdout output after stderr in the final error message
launcher.py
Refactor standard‐output retrieval to return aggregated text
  • Change _get_std_output signature to return a single string
  • Switch from list accumulation to using permanent storage property
  • Simplify get loop to rely on storage_text for output
launcher.py
Introduce QueueWithPermanentStorage to preserve all output
  • Define subclass of Queue that logs every item dequeued
  • Add storage_text property to concatenate decoded items
  • Use QueueWithPermanentStorage in _create_queue_for_std
launcher.py
Add handle_launch_exception for custom launch errors
  • Implement function mapping raw exceptions to descriptive errors
  • Wrap launch_mapdl raising to call handle_launch_exception
  • Provide actionable messages for MPI and license failures
launcher.py
Define specialized exceptions for MPI and license issues
  • Add NotAvailableLicenses for license-unavailable errors
  • Add IncorrectMPIConfigurationError for missing or misconfigured mpirun
errors.py
Fix typo and improve server-alive check stability
  • Rename empty_attemps to empty_attempts
  • Use raw queue output strings instead of trimmed joins
launcher.py

Assessment against linked issues

Issue Objective Addressed Explanation
#3963 Catch and report license errors from the MAPDL process terminal when no licenses are available.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added documentation Documentation related (improving, adding, etc) new feature Request or proposal for a new feature labels May 29, 2025
@germa89 germa89 self-assigned this May 29, 2025
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @germa89 - I've reviewed your changes - here's some feedback:

  • QueueWithPermanentStorage only overrides get(), but _get_std_output uses get_nowait(), so storage_text will always be empty—either override get_nowait or record items on put to ensure you capture everything.
  • The helper _get_std_output now returns a single string instead of a List[str] yet its name, signature, and docstring weren’t updated—please revise those or rename the function for clarity.
  • There’s duplicated logic building the stderr/stdout error message in check_mapdl_launch—consider extracting that into a shared helper to ensure consistent formatting.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

codecov bot commented Jun 2, 2025

Codecov Report

Attention: Patch coverage is 93.18182% with 3 lines in your changes missing coverage. Please review.

Project coverage is 89.11%. Comparing base (cce7ad1) to head (4680800).
Report is 10 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3969      +/-   ##
==========================================
+ Coverage   88.25%   89.11%   +0.85%     
==========================================
  Files         187      187              
  Lines       14935    14968      +33     
==========================================
+ Hits        13181    13338     +157     
+ Misses       1754     1630     -124     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@germa89
Copy link
Collaborator Author

germa89 commented Jun 2, 2025

@pyansys-ci-bot LGTM.

@germa89 germa89 enabled auto-merge (squash) June 2, 2025 15:02
Copy link
Contributor

@pyansys-ci-bot pyansys-ci-bot left a comment

Choose a reason for hiding this comment

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

✅ Approving this PR because germa89 said so in here 😬

LGTM

@germa89 germa89 merged commit c17460a into main Jun 2, 2025
82 of 83 checks passed
@germa89 germa89 deleted the feat/retrieving-stderr-for-better-info branch June 2, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Documentation related (improving, adding, etc) new feature Request or proposal for a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PyMAPDL does not report when there is no licenses
2 participants