# How to handle isAlreadyExistsError

**URL:** <https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540>\
**Category:** Learn\
**Created:** [May 16, 2022, 2:30pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540 "2022-05-16T14:30:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![pmidden](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/pmidden/32/2426_2.png) [@pmidden](https://discourse.haskell.org/u/pmidden)\
**Post date:** [May 16, 2022, 2:30pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/1 "2022-05-16T14:30:30Z")

</div>

I was trying to call `createDirectory` and catching `isAlreadyExistError` in order to do nothing in this case. I realized then that there is `createDirectoryIfMissing` and use it. But still I’m puzzled by the documentation for `createDirectory`, which says that:

```
`isAlreadyExistsError` The operand refers to a directory that already exists. [EEXIST]

```

Which leads me to believe that I can catch an `IOException` and do an `if isAlreadyExistsError e ...`. But that doesn’t seem possible, because the predicate is in a private module.

How is this supposed to be used?

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [May 16, 2022, 2:45pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/2 "2022-05-16T14:45:24Z")

</div>

Ah, the documentation points to a strange location. I think you can just use the one from [`System.IO.Error`](https://hackage.haskell.org/package/base-4.16.1.0/docs/System-IO-Error.html#v:isAlreadyExistsError).

---

<div class="post-metadata">

**Author:** ![mhitza](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/mhitza/32/2367_2.png) [@mhitza](https://discourse.haskell.org/u/mhitza)\
**Post date:** [May 16, 2022, 2:47pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/3 "2022-05-16T14:47:49Z")

</div>

It’s definitely System.IO.Error. The directory package Internal.Prelude re-exports definitions and under haddock that makes it seem like the function is definied within the directory package. I found this behaviour useful in a personal project, but I can see it very easily becoming confusing.

---

<div class="post-metadata">

**Author:** ![pmidden](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/pmidden/32/2426_2.png) [@pmidden](https://discourse.haskell.org/u/pmidden)\
**Post date:** [May 16, 2022, 3:39pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/4 "2022-05-16T15:39:51Z")

</div>

Confusing indeed. I click on ìsAlreadyExistError` and get to a (for me) relatively random module and then have to Hoogle search my way to the right function?

---

<div class="post-metadata">

**Author:** ![sjakobi](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sjakobi/32/614_2.png) [@sjakobi](https://discourse.haskell.org/u/sjakobi)\
**Post date:** [May 16, 2022, 4:00pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/5 "2022-05-16T16:00:35Z")

</div>

Marking `directory`'s internal prelude `not-home` for haddock should make the link target `System.IO.Error`.

---

<div class="post-metadata">

**Author:** ![pmidden](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/pmidden/32/2426_2.png) [@pmidden](https://discourse.haskell.org/u/pmidden)\
**Post date:** [May 17, 2022, 6:20am UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/6 "2022-05-17T06:20:58Z")

</div>

Since I don’t know how to do that, I opened an issue:

> <https://github.com/haskell/directory/issues/137>
>
> I described the problem here:
> 
> http://discourse.haskell.org/t/how-to-handle-i…salreadyexistserror/4540/2
> 
> In \`createDirectory\` the link to \`isAlreadyExistError\` is to an internal module.
> 
> It has been suggested by sjakobi that "Marking directory's internal prelude not-home for haddock should make the link target System.IO.Error.".

Let’s see if somebody fixes it.

---

<div class="post-metadata">

**Author:** ![mhitza](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/mhitza/32/2367_2.png) [@mhitza](https://discourse.haskell.org/u/mhitza)\
**Post date:** [May 17, 2022, 11:47am UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/7 "2022-05-17T11:47:26Z")

</div>

If you’d like to contribute directly on that change. This haddock manual section should be of interest [Documentation and Markup — Haddock 1.0 documentation](https://haskell-haddock.readthedocs.io/en/latest/markup.html?highlight=not-home#module-attributes)

Would require a patch with the following options pragma included in that module source code `{-# OPTIONS_HADDOCK not-home #-}`

---

<div class="post-metadata">

**Author:** ![hasufell](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hasufell/32/1250_2.png) [@hasufell](https://discourse.haskell.org/u/hasufell)\
**Post date:** [May 17, 2022, 4:19pm UTC](https://discourse.haskell.org/t/how-to-handle-isalreadyexistserror/4540/8 "2022-05-17T16:19:52Z")

</div>

I use something like this:

```haskell
hideError :: (MonadIO m, MonadCatch m) => IOErrorType -> m () -> m ()
hideError err = handleIO (\e -> if err == ioeGetErrorType e then pure () else liftIO . ioError $ e)

hideErrorDef :: (MonadIO m, MonadCatch m) => IOErrorType -> a -> m a -> m a
hideErrorDef err def =
  handleIO (\e -> if err == ioeGetErrorType e then pure def else liftIO $ ioError e)

```

(can also expand it to `hideErrors :: [IOErrorType] -> ...`)

Then:

```haskell
  hideError alreadyExistsErrorType $ createDirectory "foo"

```
