@@ -152,14 +152,21 @@ export abstract class Loader {
152152 else effects . output . write ( faint ( "[stale] " ) ) ;
153153 } else return effects . output . write ( faint ( "[fresh] " ) ) , outputPath ;
154154 const tempPath = join ( this . sourceRoot , ".observablehq" , "cache" , `${ this . targetPath } .${ process . pid } ` ) ;
155+ const errorPath = tempPath + ".err" ;
156+ const errorStat = await maybeStat ( errorPath ) ;
157+ if ( errorStat ) {
158+ if ( errorStat . mtimeMs > loaderStat ! . mtimeMs && errorStat . mtimeMs > - 1000 + Date . now ( ) )
159+ throw new Error ( "loader skipped due to recent error" ) ;
160+ else await unlink ( errorPath ) . catch ( ( ) => { } ) ;
161+ }
155162 await prepareOutput ( tempPath ) ;
156163 const tempFd = await open ( tempPath , "w" ) ;
157164 try {
158165 await this . exec ( tempFd . createWriteStream ( { highWaterMark : 1024 * 1024 } ) , effects ) ;
159166 await mkdir ( dirname ( cachePath ) , { recursive : true } ) ;
160167 await rename ( tempPath , cachePath ) ;
161168 } catch ( error ) {
162- await unlink ( tempPath ) ;
169+ await rename ( tempPath , errorPath ) ;
163170 throw error ;
164171 } finally {
165172 await tempFd . close ( ) ;
@@ -223,7 +230,7 @@ class CommandLoader extends Loader {
223230 subprocess . on ( "close" , resolve ) ;
224231 } ) ;
225232 if ( code !== 0 ) {
226- throw new Error ( `exited with code ${ code } ` ) ;
233+ throw new Error ( `loader exited with code ${ code } ` ) ;
227234 }
228235 }
229236}
0 commit comments