Bonjour tout le monde qui gère les erreurs

9

Écrivez un programme ou une fonction avec les fonctionnalités suivantes:

  • Le programme / fonction tente d'abord d'écrire la chaîne Hello, world!dans le flux de sortie standard. (Aucune autre forme de sortie n'est acceptable pour ce défi, car l'accent est mis sur les E / S plutôt que sur le comportement trivial du programme lui-même.) Selon qu'il a réussi:
    • S'il a réussi à sortir Hello, world!, le programme / fonction se ferme sans autre comportement.
    • S'il n'a pas produit la sortie correcte en raison d'une erreur, le programme / la fonction tente d'écrire la chaîne Error writing "Hello, world!"dans le flux d'erreur standard. (Aux fins de ce défi, vous n'avez pas besoin de la gestion des erreurs pour la gestion des erreurs elle-même.)

Clarifications

  • Votre programme / fonction sera exécuté sans entrée (sauf s'il est écrit dans un langage qui nécessite absolument une entrée pour fonctionner, auquel cas il sera exécuté avec l'entrée la plus simple possible).

  • Lorsque vous produisez une sortie, vous pouvez également produire une seule nouvelle ligne de fin si vous le souhaitez, mais cela n'est pas obligatoire.

  • La définition de «l'écriture d'erreur sur la sortie standard» que votre programme implémente doit traiter au moins les cas suivants comme des erreurs:

    • La sortie standard étant inexistante (c'est-à stdout- dire un descripteur de fichier fermé, aucun descripteur de fichier 1 n'existe, ou cependant ces cas se traduisent dans la langue et le système d'exploitation que vous utilisez);
    • Sortie standard faisant référence à un fichier sur un disque qui n'a plus d'espace libre;
    • Sortie standard se connectant à un autre programme, qui a déjà fermé son extrémité de la connexion.

    et doit traiter au moins les cas suivants comme un succès (c'est-à-dire pas une erreur):

    • La sortie standard se connecte à un terminal et Hello, world!s'affiche à l'écran.
    • La sortie standard se connecte à un fichier et Hello, world!est écrite dans le fichier.

    Vous pouvez choisir les détails de ce qui compte comme une erreur de sortie, tant qu'il est conforme aux règles ci-dessus.

  • Votre programme / fonction ne doit pas se bloquer lors de la rencontre de l'une des situations d'erreur répertoriées ci-dessus. C'est à vous de choisir le code de sortie que vous utilisez.

  • Votre programme / fonction ne doit pas décrire la nature de l'erreur rencontrée sur le flux d'erreur standard; il devrait simplement imprimer la chaîne spécifiée ci-dessus. La sortie étrangère sur erreur standard (par exemple les avertissements du compilateur) n'est légale que si elle est produite sans condition, indépendamment du fait qu'une erreur soit rencontrée ou non.

  • Votre programme ne doit fonctionner que sur un seul système d'exploitation (bien qu'il doit s'agir d'un système sur lequel les erreurs répertoriées ci-dessus ont un sens; j'ai essayé de les garder suffisamment générales pour fonctionner sur la plupart des systèmes d'exploitation grand public multitâche, mais des systèmes d'exploitation plus étranges peuvent bien être exclus de ce défi). Si votre programme n'est pas portable, indiquez les hypothèses qu'il doit exécuter dans le titre de votre soumission.

  • Cette tâche peut ne pas être possible dans toutes les langues (toutes les langues ne permettent pas à un programme de gérer les erreurs de sortie de manière personnalisée). Vous devrez choisir une langue où cela est possible.

  • Assurez-vous que votre programme / fonction fonctionne! Ne vous fiez pas seulement à la documentation des fonctions de la bibliothèque pour faire ce qu'ils disent faire. La gestion des erreurs des fonctions de sortie simples s'avère souvent être rompue dans la pratique, même si les fonctions prétendent gérer les erreurs en théorie.

Cas de test

Voici un moyen de simuler chacune des conditions d'erreur ci-dessus en utilisant bashsous Linux (vous n'avez pas besoin d'utiliser Linux, mais c'est probablement le système le plus simple pour tester cela):

your_program_here >&-           # nonexistent stdout
your_program_here > /dev/full   # out of disk space
mkfifo test  # note: change "test" to a filename that isn't in use
true < test &
your_program_here > test        # connecting to a program that doesn't want input
rm test      # clean up the FIFO we used earlier

Les deux premiers cas de test sont déterministes. Le dernier n'est pas (il repose sur une condition de course); à des fins de test, je recommande d'ajouter un délai entre le début de votre programme et la sortie réelle à la sortie standard, afin de garantir que la condition de concurrence critique est résolue de la manière qui expose l'erreur.

Condition de victoire

C'est un défi de , donc plus court est mieux. Comme (presque) toujours, nous mesurons la longueur du programme en octets.


la source
1
Savez-vous s'il existe un moyen de tester cela sous Windows? Je peux tester le premier critère, mais pas la partie sur le disque plein ...
Stewie Griffin
Pour réduire les conditions de concurrence, pourriez-vous utiliser sleep 1 < test; (sleep 2; your_program_here) > test?
Neil
En relation
JayCe

Réponses:

6

Bash , 71 60 octets

h=Hello,\ world!
(echo $h)2>&-||echo Error writing \"$h\">&2

Essayez-le en ligne!

Comment ça fonctionne

Après avoir enregistré Hello, world!dans la variable h , nous procédons comme suit.

Tout d'abord, (echo $h)2>&-tente d'imprimer Hello, world!sur STDOUT. 2>&-est requis pour empêcher l'affichage du message d'erreur echo: erreur d'écriture: descripteur de fichier incorrect en cas d'échec de l'écriture. Étant donné que l'écriture dans un canal nommé qui n'accepte pas d'entrée tuerait le programme Bash avec le signal 13 (SIGPIPE), nous exécutons la commande dans un sous-shell ( (...)), donc seul le sous-shell sera tué.

Enfin, si l'impression vers STDOUT a échoué, le sous-shell se terminera avec un code d'état non nul (141 pour SIGPIPE, 1 pour une erreur générique), echo Error writing \"$h\">&2imprime donc le message souhaité à STDERR.

Dennis
la source
2

Python 2 , 65 octets

h='Hello, world!'
try:print h
except:exit('Error writing "%s"'%h)

Deux octets pourraient être enregistrés en imprimant des guillemets simples.

Essayez-le en ligne!

Dennis
la source
1

Zsh , 55 octets

h=Hello,\ world!
2>&-<<<$h||<<<'Error writing "'$h\">&2

Contrairement à son cousin Bash, Zsh refuse de mourir à cause d'une pipe cassée.

Essayez-le en ligne!

Dennis
la source
1

C (gcc) , 87 86 octets

f(){signal(13,1);write(1-puts("Hello, world!"),"Error writing \"Hello, world!\"",29);}

Essayez-le en ligne!

Non golfé

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void f(void)
{
    signal(SIGPIPE, SIG_IGN); // Works (and is required) on TIO. YMMV
    int fd = (puts("Hello, world!")) < 0 ? 2 : -13;
    write(fd, "Error writing \"Hello, world!\"", 29);
}
Dennis
la source
comment savez-vous ce que le retour met? ici dit juste que c'est> = 0 pour que tout soit bien ...
RosLuP
putsrenvoie le nombre d'octets qui ont été écrits ou -1 en cas d'erreur, il renvoie donc 14 (Hello World plus newline) ou -1 . (Cela peut être spécifique à la plate-forme, mais voici comment cela se comporte avec la glibc.)
Dennis
K & R2 dit qu'il retourne EOF [-1 pratiquement] si erreur; ou une valeur non négative si tout va bien
RosLuP
1
Sur PPCG, les langages sont définis par leur implémentation, et gcc / glibc se comportent comme je l'ai dit.
Dennis
je préfère l'ancien livre
RosLuP
1

PowerShell, 80 octets

try{echo($h="Hello, World!") -ea 4}catch{$host.ui|% *rL* "Error writing ""$h"""}

expliqué:

try{
    #Attempt to 'echo' (write output) the string, and assign it to $h
    #Make sure the 'error action' is set to '4' to make it a terminating error.
    echo($h="Hello, World!") -ea 4
} catch { 
    #Use the "WriteErrorLine" function in $host.ui to stderr
    $host.ui|% *rL* "Error writing ""$h"""
}

n'ont pas réussi à réellement essayer cela quand il fait une erreur, mais cela devrait certainement ~ fonctionner ~.

colsw
la source
Le message d'erreur doit être écrit dans STDERR . L'écrire dans STDOUT n'est pas possible si une erreur se produit lors de la première tentative d'écriture.
Dennis
@Dennis merci pour cela, mis à jour là-bas, n'a pas lu la question entièrement.
colsw
Afaict PowerShell ne détecte que les exceptions fatales, donc vous en auriez besoin Write-Host -ErrorAction Stopou quelque chose comme ça. En outre, le throwproduit produit une ingormation de débogage supplémentaire en dehors de la ligne qu'il doit imprimer, qui doit d'ailleurs avoir un W minuscule et des guillemets doubles autour de la chaîne HW.
Dennis
@Dennis, les informations de débogage supplémentaires m'ont écrasé, réponse mise à jour là maintenant.
colsw
1

Javascript, 79 76 octets

try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}
Matthew Roh
la source
Notez que la chaîne que vous devez sortir est 'Hello, world!', qui est un octet de plus que celle que vous utilisez. En outre, je suppose que l'attribution aà l'intérieur de l'appel console.logserait plus courte (1B) et la suppression du point-virgule après l' l.log(a)enregistrement d'un autre octet.
Luke
@Luke Merci, c'était une grosse erreur!
Matthew Roh
1
try{(l=console).log(a="Hello, world!")}catch(e){l.error('Error writing '+a)}pour 76 octets. Tout d'abord, consoleest affecté à l, puis "Hello, world!'est affecté à a, puis il est exécuté.
Luke
0

Perl 5, 51 octets

nécessite -M5.01, qui est gratuit

say$h="Hello, world!"or die"Error writing \"$h\"$/"

Testé dans Strawberry Perl 5.24.0 en exécutant le programme tel quel (imprimé sur la sortie standard) et en exécutant

print f $h="Hello, world!"or die"Error writing \"$h\"$/"

(imprimé à l'erreur standard). Je ne sais pas comment tester d'autres erreurs avec Strawberry, mais elles doivent être traitées de la même manière….

msh210
la source
Pour autant que je sache, cela ne fonctionne pas. tio.run/nexus/bash#jY3NDoIwEITvfYq1IXCiiD83ys3Ei2/… (Il manque également une virgule à la chaîne.)
Dennis
Je ne sais pas quoi faire de cette page à laquelle vous avez lié; pouvez-vous expliquer, s'il vous plaît? Notez également que le script doit fonctionner sur un seul système d'exploitation. Et je vais ajouter la virgule; Merci.
msh210
La sortie doit s'afficher Hello, world!après === 1 ===et rien après les autres. Le débogage ne doit rien afficher après === 1 ===et Error writing "Hello, world!"après les autres. Je suis conscient que votre programme n'a pas à fonctionner sur TIO, mais print f...affiche les messages d'erreur prévus alors que le programme d'origine ne le fait pas.
Dennis
"Output" et "Debug" n'affichent tous les deux autant que je sache. Je ne sais pas non plus ce que sont les sections "En-tête" et "Pied de page". Et je ne connais pas du tout TIO, mais notez que Strawberry Perl fonctionne sur MS Windows.
msh210
Pointe du chapeau à Dennis pour l'idée de stocker la chaîne dans une variable (même si j'y aurais probablement pensé si je ne l'avais pas vue là-bas).
msh210
0

REXX, 1111106 octets

signal on notready
a='Hello, world!'
_=lineout(,a)
exit
notready:_=lineout('stderr','Error writing "'a'"')

Le programme repose sur l'existence d'un flux appelé «stderr». Ce ne sera probablement pas le cas sur les systèmes IBM.

idrougge
la source
0

C, 77 octets

f(a){a="Error writing \"Hello, world!\"";write(1,a+15,13)-13&&write(2,a,29);}

pour appeler

main(){f(1); return 0;}
RosLuP
la source
Sur quelle plateforme avez-vous testé cela? Cela ne fonctionne pas sous Linux si un tube cassé est rencontré.
Dennis
0

R , 91 octets

s="Hello, world!"
tryCatch(cat(s),error=function(e)cat('Error writing "','"',file=2,sep=s))

Essayez-le en ligne!

J'ai essayé de l'erreur en l'exécutant avec cat(s,file=12)au lieu de cat(s), et il imprime le texte correct sur stderr. C'est une invalid connectionerreur sinon.

JayCe
la source
Une idée de comment tester d'autres erreurs de sortie?
JayCe