Repository: python-pillow/Pillow

Issue:
ImageGrab.grabclipboard() prints error instead of raising it on Linux X11 with text in the clipboard
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?
Call `ImageGrab.grabclipboard()` on Linux running X11 while the clipboard contains text

### What did you expect to happen?
Raise all errors (so exception handling can be done)

### What actually happened?
First, `UnidentifiedImageError` is raised which is fine as it can be suppressed by using exception handling.
However a second error happens `Error: target image/png not available` but instead of being raised it's printed directly to the console, probably since it's what xclip is sending to stdout. 

Because of this simply calling `ImageGrab.grabclipboard()` with text in the clipboard will always print to the console. I'm using Pillow to constantly check the clipboard for new images so this behaviour causes the console to be flooded with error messages. 

### What are your OS, Python and Pillow versions?

* OS: KDE Neon 5.27 (Ubuntu Jammy)
* Python: 3.10.6
* Pillow: 9.5.0

<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->

The following code should print nothing when the clipboard is text but instead prints the error every loop:
```python
import time
from PIL import Image, ImageGrab

print('Reading from clipboard')

img = None
while True:
    try:
        img = ImageGrab.grabclipboard()
    except:
        pass
    else:
        if isinstance(img, Image.Image):
            print("Successful Image Grab")

    time.sleep(1)
```



Discussion:
Line 144, I suppose

https://github.com/python-pillow/Pillow/blob/e3cb4bb8e00fcaf4c3e0783f7c02e51372595659/src/PIL/ImageGrab.py#L135-L149

Add `stderr=subprocess.DEVNULL`? Or maybe store `stderr` somewhere and check if it's empty?

Resolving patch:
diff --git a/src/PIL/ImageGrab.py b/src/PIL/ImageGrab.py
--- a/src/PIL/ImageGrab.py
+++ b/src/PIL/ImageGrab.py
@@ -141,8 +141,11 @@ def grabclipboard():
             msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux"
             raise NotImplementedError(msg)
         fh, filepath = tempfile.mkstemp()
-        subprocess.call(args, stdout=fh)
+        err = subprocess.run(args, stdout=fh, stderr=subprocess.PIPE).stderr
         os.close(fh)
+        if err:
+            msg = f"{args[0]} error: {err.strip().decode()}"
+            raise ChildProcessError(msg)
         im = Image.open(filepath)
         im.load()
         os.unlink(filepath)


Test patch: