Qual é a diferença - técnica, filosófica, conceitual ou outra - entre
raise "foo"
e
raise Exception.new("foo")
?
fonte
Qual é a diferença - técnica, filosófica, conceitual ou outra - entre
raise "foo"
e
raise Exception.new("foo")
?
Tecnicamente, o primeiro gera um RuntimeError com a mensagem definida como "foo"
e o segundo gera uma Exceção com a mensagem definida como "foo"
.
Praticamente, há uma diferença significativa entre quando você deseja usar o primeiro e quando deseja usar o último.
Simplificando, você provavelmente RuntimeError
não deseja um Exception
. Um bloco de resgate sem um argumento pegará RuntimeErrors
, mas NÃO pegará Exception
s. Portanto, se você gerar um Exception
em seu código, este código não o pegará:
begin
rescue
end
Para capturar o, Exception
você terá que fazer o seguinte:
begin
rescue Exception
end
Isso significa que, em certo sentido, um Exception
é um erro "pior" do que um RuntimeError
, porque você precisa trabalhar mais para se recuperar dele.
Portanto, o que você deseja depende de como seu projeto trata de erros. Por exemplo, em nossos daemons, o loop principal tem um resgate em branco que os captura RuntimeErrors
, relata e depois continua. Mas em uma ou duas circunstâncias, queremos que o daemon realmente morra com um erro e, nesse caso, levantamos um Exception
, que vai direto ao nosso "código normal de tratamento de erros" e sai.
E, novamente, se você está escrevendo o código da biblioteca, provavelmente deseja um RuntimeError
, não um Exception
, pois os usuários de sua biblioteca ficarão surpresos se isso gerar erros que um rescue
bloco em branco não pode detectar, e eles levarão um momento para perceber o porquê.
Finalmente, devo dizer que RuntimeError
é uma subclasse da StandardError
classe, e a regra real é que, embora você possa raise
qualquer tipo de objeto, o espaço rescue
em branco , por padrão, só capturará qualquer coisa que herde de StandardError
. Todo o resto tem que ser específico.
RuntimeError < StandardError < Exception
[2] portanto, que segundo bloco de código vai pegar tanto uma exceção e uma RuntimeError [3] é interessante / estranho que o aumento e o resgate "simples" aconteçam para funcionar com aquela Exception em particular [4]. Talvez a regra seja aumentar RuntimeError para o código do cliente, mas aumentar e resgatar as próprias Exceptions personalizadas dentro do próprio código?StandardError
. Não precisa ser mais complicado do que algumas linhas comoclass MissingArgumentsError < StandardError; end
.Da documentação oficial:
Sem argumentos, levanta a exceção em
$!
ou levanta umRuntimeError
se$!
for nulo. Com um únicoString
argumento, ele gera aRuntimeError
com a string como uma mensagem. Caso contrário, o primeiro parâmetro deve ser o nome de umaException
classe (ou um objeto que retorna umaException
exceção quando enviada). O segundo parâmetro opcional define a mensagem associada à exceção e o terceiro parâmetro é uma matriz de informações de retorno de chamada. As exceções são capturadas pela cláusula de resgate debegin...end
blocos.fonte