Skip to content

fix(deck.gl-geotiff): raise COG open failures through onError - #652

Merged
kylebarron merged 3 commits into
developmentseed:mainfrom
earlybard:fix/raise-cog-open-errors
Sep 21, 2026
Merged

kylebarron merged 3 commits into
developmentseed:mainfrom
earlybard:fix/raise-cog-open-errors

Conversation

@earlybard

Copy link
Copy Markdown
Contributor

What I am changing

COGLayer and MultiCOGLayer kick off the GeoTIFF open from updateState and never look at the promise again. If the header fetch or CRS lookup fails you get an unhandled rejection in the console, onError stays silent, and the layer just sits there empty.

Both now catch that and hand it to Layer.raiseError, so props.onError fires, and Deck's onError after it unless you return true.

How you can test it

new MultiCOGLayer({
  id: "missing",
  sources: { red: { url: "https://example.com/missing.tif" } },
  composite: { r: "red" },
  onError: (error) => console.warn(error.message, error.cause),
});

On main: unhandled rejection, no callback. With this: one loading COG sources: … call. There's a unit test per layer too, and both fail on main.

Related Issues

Closes #205. Takes over from #206, which did the same for COGLayer only and has drifted out of date.

AI disclosure: written with Claude Code as a code assistant, reviewed by me.

COGLayer and MultiCOGLayer open their GeoTIFFs from updateState without
awaiting the promise, so a header fetch or CRS resolution that fails
rejects with nothing attached: the browser logs an unhandled rejection,
onError never fires and the layer stays empty. Both opens now route a
rejection through Layer.raiseError, which calls props.onError and falls
back to the Deck-level handler, the path deck.gl uses for a failed async
data load.

Closes developmentseed#205

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added the fix label Sep 17, 2026
@earlybard
earlybard marked this pull request as ready for review September 17, 2026 08:39
@kylebarron

Copy link
Copy Markdown
Member

Thanks @earlybard. Can I ask how you're using deck.gl-raster?

@earlybard

Copy link
Copy Markdown
Contributor Author

Hey @kylebarron. I'm building a COG viewer for open Geoscience Australia data. I'm:

  • Streaming 16 bit COGs to the browser, rendering with MapLibre + deck.gl
  • Using MosaicLayer + MultiCOGLayer to render many scenes as a mosaic
  • Rescaling to 8 bit dynamically, allowing histogram manipulation
  • Supporting band selection and mixing.

There are some tricky mosaic-like issues I'll be tackling next, e.g. controlling z-index of scenes within the mosaic, and not rendering fully occluded scenes.

Thanks again!

this.clearState();
this._parseGeoTIFF();
this._parseGeoTIFF().catch((error: Error) =>
this.raiseError(error, "loading GeoTIFF"),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh interesting is raiseError an upstream method in the base deck.gl Layer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep it is. Marked (Internal) in the docstring but the types are public. Not sure how you feel about that!

My use case is a display in my UI if a GeoTIFF fails to load.

The alternative is a new prop like onGeoTIFFError, but this seemed easier + hooks into Deck's error handling.

@kylebarron kylebarron left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@kylebarron
kylebarron merged commit 7824b7f into developmentseed:main Sep 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Internal errors aren't passed to an onError callback

2 participants