Skip to content

Raise an informative error when a fetch query matches no files - #1085

Open
lobennett wants to merge 2 commits into
neurostuff:mainfrom
lobennett:enh/fetch-informative-error
Open

Raise an informative error when a fetch query matches no files#1085
lobennett wants to merge 2 commits into
neurostuff:mainfrom
lobennett:enh/fetch-informative-error

Conversation

@lobennett

@lobennett lobennett commented Jun 24, 2026

Copy link
Copy Markdown

fetch_neurosynth/fetch_neuroquery passed an unmatched query straight through _fetch_database, which returned an empty list and silently yielded no data — so a typo'd source/vocab/type looked like an empty result with no hint.

This raises an informative ValueError when a query matches no files in the bundled manifest, listing the available values per entity (version/vocab/source/type) for the requested data source. The match happens before any download, so the error is immediate. Adds a small pure helper (_get_available_entities) with unit tests, plus offline tests that the fetch functions raise.

Closes #640

Before / after

>>> nimare.extract.fetch_neurosynth(vocab="not_a_real_vocab", return_type="files")

Before:

[]        # silent empty result, no hint

After:

ValueError: No files matched the query {'vocab': 'not_a_real_vocab', 'data': 'neurosynth', 'version': '7'}.
Available options for data-neurosynth are: version: 3, 4, 5, 6, 7;
vocab: LDA100, LDA200, LDA400, LDA50, terms; source: abstract; type: tfidf, weight.

Summary by Sourcery

Raise an informative error when metadata fetch queries match no files in bundled manifests and surface available query options.

Bug Fixes:

  • Prevent silent empty results from fetch_neurosynth and fetch_neuroquery when a query matches no files by raising a descriptive ValueError instead.

Enhancements:

  • Add a helper to derive available entity values (version, vocab, source, type) from database manifests for inclusion in error messages.

Tests:

  • Add unit tests for the available-entities helper and offline tests verifying fetch_neurosynth and fetch_neuroquery raise on unmatched queries.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@welcome

welcome Bot commented Jun 24, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! We have detected this is the first time you have contributed to NiMARE. Please check out our contributing guidelines.
We invite you to list yourself as a NiMARE contributor, so if your name is not already mentioned, please modify the .zenodo.json file with your data right above Angie's entry. Example:

{
  "name": "Contributor, New",
  "affiliation": "Department of Psychology, Some University",
  "orcid": "<your id>"
},
{
  "name": "Laird, Angela R.",
  "affiliation": "Florida International University",
  "orcid": "0000-0003-3379-8744"
},

Of course, if you want to opt out this time there is no problem at all with adding your name later. You will be always welcome to add it in the future whenever you feel it should be listed.

@sourcery-ai

sourcery-ai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds pre-download validation of fetch queries in the extraction utilities so unmatched queries raise an informative ValueError listing available entity options, via a new helper that parses the database manifest, along with unit tests covering the helper and the new error behavior for neurosynth and neuroquery fetchers.

Sequence diagram for fetch_neurosynth validation and error on unmatched query

sequenceDiagram
    actor User
    participant FetchNeurosynth
    participant _fetch_database
    participant _get_available_entities

    User->>FetchNeurosynth: fetch_neurosynth(vocab, return_type)
    FetchNeurosynth->>_fetch_database: _fetch_database(search_pairs, database_url, out_dir, overwrite)

    _fetch_database->>_fetch_database: scan database_file_manifest for search_pairs

    alt no_matching_databases
        _fetch_database->>_get_available_entities: _get_available_entities(database_file_manifest, data)
        _get_available_entities-->>_fetch_database: available_entities
        _fetch_database-->>User: ValueError
    else matching_databases_found
        _fetch_database-->>FetchNeurosynth: found_files
        FetchNeurosynth-->>User: data_or_files
    end
Loading

File-Level Changes

Change Details Files
Introduce helper to compute available manifest entity values used for error messages when no database entries match a query.
  • Add _get_available_entities to parse feature filenames in the database manifest into distinct version/vocab/source/type values, optionally scoped to a specific data source.
  • Parse feature filename parts split by underscores, extract key-value pairs separated by '-', and aggregate values into sets per searchable entity.
  • Return a compact dict of entities to sorted lists of values, omitting entities with no values.
nimare/extract/extract.py
Raise an informative ValueError from _fetch_database when no databases match the search query, instead of silently returning no files.
  • After scanning the manifest, detect the case where found_databases is empty and treat it as an error.
  • Use _get_available_entities filtered by the requested data source to build a human-readable list of valid options.
  • Raise ValueError that includes the original query and the available options string, before any downloads occur.
nimare/extract/extract.py
Add tests to verify entity extraction and new error behavior for neurosynth and neuroquery fetch functions.
  • Test that _get_available_entities returns source-scoped, sorted, distinct values and does not leak entities between different data sources.
  • Add offline tests asserting fetch_neurosynth and fetch_neuroquery raise ValueError on unmatched vocab queries and that the neurosynth error message surfaces an available vocab option.
  • Reuse temporary directories and pytest’s exception assertion helpers to keep tests isolated and deterministic.
nimare/tests/test_extract.py

Assessment against linked issues

Issue Objective Addressed Explanation
#640 When a user supplies an incompatible or unmatched query to fetch_neuroquery or fetch_neurosynth, the functions should raise an error instead of silently returning no data.
#640 The raised error for unmatched queries in fetch_neuroquery or fetch_neurosynth should be informative, including available patterns/options (e.g., versions, vocabs, sources, types) that the user can choose from.

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In _fetch_database, the error message formats data-{search_pairs.get('data')} even when data might be None or when no available entities are found, which can lead to awkward messages like data-None or an empty options list; consider guarding this formatting and falling back to a more generic message in those cases.
  • The _get_available_entities parser assumes entity segments are separated by underscores and always in key-value form (e.g., version-7), which tightly couples it to the current naming convention; consider constraining parsing to known keys or using a regex so that unexpected filename changes or additional underscores do not silently produce incorrect entity mappings.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_fetch_database`, the error message formats `data-{search_pairs.get('data')}` even when `data` might be `None` or when no available entities are found, which can lead to awkward messages like `data-None` or an empty options list; consider guarding this formatting and falling back to a more generic message in those cases.
- The `_get_available_entities` parser assumes entity segments are separated by underscores and always in `key-value` form (e.g., `version-7`), which tightly couples it to the current naming convention; consider constraining parsing to known keys or using a regex so that unexpected filename changes or additional underscores do not silently produce incorrect entity mappings.

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.

Address review feedback on PR neurostuff#1085:

- Constrain _get_available_entities to a known-key allowlist (data,
  version, vocab, source, type) so an unexpected key-value segment in a
  feature filename can no longer silently mismap entities.
- Guard the _fetch_database no-match message: fall back to a generic
  scope ("the requested database") when the query has no data key
  (avoids "data-None"), and emit a generic message pointing at the
  manifest when no entity options are available.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lobennett

Copy link
Copy Markdown
Author

Addressed both review points in 538fb9a:

  • data-None / empty options in _fetch_database: the message now falls back to a generic scope ("the requested database") when the query has no data key, and emits a generic "No matching entries were found … see the database file manifest for valid patterns." message when no entity options are available. It still leads with "No files matched the query …".
  • _get_available_entities parser: replaced the "any hyphenated segment is an entity" logic with a known-key allowlist (data, version, vocab, source, type). Unknown key-value segments are ignored, so a filename-format change can no longer silently mismap entities. I used an allowlist rather than a regex — it's stricter and avoids importing re for a simple partition('-').

Added three tests (unknown-segment ignored, data-None omitted, generic fallback); pytest nimare/tests/test_extract.py passes (12) and flake8 is clean.

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.54%. Comparing base (ba8d921) to head (538fb9a).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1085      +/-   ##
==========================================
+ Coverage   85.50%   85.54%   +0.03%     
==========================================
  Files          56       56              
  Lines       11248    11274      +26     
==========================================
+ Hits         9618     9644      +26     
  Misses       1630     1630              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Raise informative error when fetch_neuroquery/fetch_neurosynth query does not match available patterns

1 participant